今天给同学们讲一下在项目开发中我们经常会碰到这样的需求,动态的添加或者删除某一行显示数据并且重新布局Frame,那么废话不多说,直接上代码!先看演示视频:
iOS开发-模仿动态增加或者删除cell并自动增加变化高度.gif
//
// ZZCustomAddView.h
// 动态变化frame
//
// Created by new on 2017/7/21.
// Copyright © 2017年 we-smart Co., LTD. All rights reserved.
//
#import <UIKit/UIKit.h>
@class ZZCustomAddView;
@protocol ZZCustomAddViewDelegate <NSObject>
@optional
- (void)customAddView:(ZZCustomAddView *)customAddView didClickPrintBtnWithContentsArr:(NSMutableArray *)contentsArr;
@end
@interface ZZCustomAddView : UIView
+ (instancetype)customAddView;
@property (weak, nonatomic) id <ZZCustomAddViewDelegate> delegate;
@end
//
// ZZCustomAddView.m
// 动态变化frame
//
// Created by new on 2017/7/21.
// Copyright © 2017年 we-smart Co., LTD. All rights reserved.
//
// 添加按钮的父类view的高度
#define kViewHeight 40
// 添加按钮的宽
#define kAddBtnWidth 25
#import "ZZCustomAddView.h"
@interface ZZCustomAddView()
/**
* view的个数
*/
@property (assign, nonatomic) NSInteger viewCount;
/**
* 添加的新的view
*/
@property (weak, nonatomic) UIView *bgView;
/**
* 打印按钮
*/
@property (weak, nonatomic) UIButton *printBtn;
@end
@implementation ZZCustomAddView
+ (instancetype)customAddView
{
return [[self alloc] init];
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setUpSubViews];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
if (self = [super initWithCoder:decoder]) {
[self setUpSubViews];
}
return self;
}
- (void)setUpSubViews
{
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kViewHeight)];
[self addSubview:bgView];
self.bgView = bgView;
UIView *addView = [self addANewViewWithFrame:CGRectMake(0, 0, self.frame.size.width, kViewHeight)];
[bgView addSubview:addView];
UIButton *printBtn = [[UIButton alloc] init];
printBtn.frame = CGRectMake((self.frame.size.width - 80) / 2, CGRectGetMaxY(bgView.frame) + 5, 80, 30);
printBtn.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.5f];
[printBtn setTitle:NSLocalizedString(@"确定", nil) forState:UIControlStateNormal];
[printBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[printBtn addTarget:self action:@selector(printBtnClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:printBtn];
self.printBtn = printBtn;
// 默认设置有一个
self.viewCount = 0;
}
- (UIView *)addANewViewWithFrame:(CGRect)frame
{
UIView *newView = [[UIView alloc] initWithFrame:frame];
// 添加按钮
UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
addBtn.frame = CGRectMake(10, (kViewHeight - kAddBtnWidth) / 2, kAddBtnWidth, kAddBtnWidth);
[addBtn setImage:[UIImage imageNamed:@"tianjia"] forState:UIControlStateNormal];
[addBtn addTarget:self action:@selector(addButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:addBtn];
// 文本框
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(CGRectGetMaxX(addBtn.frame) + 5, 5, newView.frame.size.width - CGRectGetMaxX(addBtn.frame) - 5 - 10, kViewHeight - 10)];
textField.placeholder = @"请编辑";
textField.backgroundColor = [UIColor whiteColor];
textField.font = [UIFont systemFontOfSize:14];
[newView addSubview:textField];
return newView;
}
#pragma mark - method
- (void)addButtonClick:(UIButton *)addBtn
{
// 0.退出第一响应者
[self endEditing:YES];
if ([addBtn.currentImage isEqual:[UIImage imageNamed:@"shanchu"]]) { // 删除
UIView *superView = addBtn.superview;
[superView removeFromSuperview];
// 1.删除到最后一个视图
if (self.bgView.subviews.count == 1) {
UIView *currentView = self.bgView.subviews[0];
currentView.frame = CGRectMake(0, 0, self.bgView.frame.size.width, kViewHeight);
} else { // 有多个视图
UIView *firstView = self.bgView.subviews[0];
CGFloat firstViewY = firstView.frame.origin.y;
if (firstViewY == 40) { // 第一个已经删除
firstView.frame = CGRectMake(0, 0, self.bgView.frame.size.width, kViewHeight);
}
for (NSInteger i = 0; i < self.bgView.subviews.count; i++) {
if (i > 0) {
UIView *currentView = self.bgView.subviews[I];
UIView *frontView = self.bgView.subviews[i - 1];
if (CGRectGetMaxY(currentView.frame) - CGRectGetMaxY(frontView.frame) != kViewHeight) { // 判断两个View之间y的距离
CGRect frame = currentView.frame;
frame.origin = CGPointMake(0, currentView.frame.origin.y - 40);
currentView.frame = frame;
}
}
}
}
// view个数减一个
self.viewCount--;
} else { // 添加
if (self.viewCount == 4) { // 限制只能添加5个
// 这是个过期的方法,可以自行换掉
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"至多只能添加5个" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alertView show];
return;
}
// view个数增加一个
self.viewCount++;
[addBtn setImage:[UIImage imageNamed:@"shanchu"] forState:UIControlStateNormal];
// 创建一个新的view
UIView *secondView = [self addANewViewWithFrame:CGRectMake(0, self.viewCount * kViewHeight, self.bgView.frame.size.width, kViewHeight)];
[self.bgView addSubview:secondView];
}
// 修改视图的frame
self.frame = CGRectMake(50, 100, [UIScreen mainScreen].bounds.size.width - 100, kViewHeight * self.bgView.subviews.count + 40);
self.bgView.frame = CGRectMake(0, 0, self.frame.size.width, kViewHeight * self.bgView.subviews.count);
self.printBtn.frame = CGRectMake((self.frame.size.width - 80) / 2, CGRectGetMaxY(self.bgView.frame) + 5, 80, 30);
}
- (void)printBtnClick
{
// 0.退出第一响应者
[self endEditing:YES];
// 1.取出所有的文字
NSMutableArray *contents = [NSMutableArray array];
for (UIView *subView in self.bgView.subviews) {
UITextField *tempTextField = (UITextField *)subView.subviews[1];
[contents addObject:tempTextField.text];
}
// 2.通知代理
if ([self.delegate respondsToSelector:@selector(customAddView:didClickPrintBtnWithContentsArr:)]) {
[self.delegate customAddView:self didClickPrintBtnWithContentsArr:contents];
}
}
@end
//
// ViewController.h
// 动态变化frame
//
// Created by new on 2017/7/21.
// Copyright © 2017年 we-smart Co., LTD. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
//
// ViewController.m
// 动态变化frame
//
// Created by new on 2017/7/21.
// Copyright © 2017年 we-smart Co., LTD. All rights reserved.
//
#import "ViewController.h"
#import "ZZCustomAddView.h"
@interface ViewController ()<ZZCustomAddViewDelegate>
@property (weak, nonatomic) UILabel *showLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 0.初始化添加的自定义view
ZZCustomAddView *buttonAddView = [[ZZCustomAddView alloc] initWithFrame:CGRectMake(50, 100, [UIScreen mainScreen].bounds.size.width - 100, 80)];
buttonAddView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3];
buttonAddView.delegate = self;
[self.view addSubview:buttonAddView];
// 1.数据展示
UILabel *showLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, [UIScreen mainScreen].bounds.size.height - 300, [UIScreen mainScreen].bounds.size.width - 100, 300)];
showLabel.text = @"数据展示...";
showLabel.font = [UIFont systemFontOfSize:14];
showLabel.textColor = [UIColor blackColor];
showLabel.numberOfLines = 0;
showLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:showLabel];
self.showLabel = showLabel;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES];
}
#pragma mark - ZZCustomAddViewDelegate
- (void)customAddView:(ZZCustomAddView *)customAddView didClickPrintBtnWithContentsArr:(NSMutableArray *)contentsArr
{
NSString *labelTextStr = @"";
// 循环取出text
for (NSInteger i = 0; i < contentsArr.count; i++) {
if (i == 0) {
labelTextStr = [NSString stringWithFormat:@"第%ld行text:%@", i + 1, contentsArr[I]];
} else {
labelTextStr = [NSString stringWithFormat:@"%@\n第%ld行text:%@", labelTextStr, i + 1, contentsArr[I]];
}
}
self.showLabel.text = labelTextStr;
}
@end