今天給同學們講一下在項目開發中我們經常會碰到這樣的需求,動態的添加或者刪除某一行顯示數據并且重新布局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