同一界面加载不同的UITableViewCell,如表单或者设置界面
来源:互联网 发布:艾学通排课软件 编辑:程序博客网 时间:2024/06/05 05:11
在做APP时,经常会做到像设置界面,或表单填写这样的界面,实现的方式有多种,比如每一行用UIControl来做,最近做的一个APP里,我还是用UITableViewCell实现的,总结出了一套自认为简单实用的方法,如果您有什么自己惯用的方法,希望在评论中留言呀^_^,互相学习一下!
好了,进入正题,假如我们现在要在APP中实现一个下面这样的表单填写界面:
实现过程:
(1)一共四行,所以创建4个UITableViewCell,下面的按钮不放在UITableView里做,因为每个cell都只用一次,所以我把4个cell都放在一个xib文件中。所以先创建一个FillFormCell.xib,然后在里面拖出4个UITableViewCell,然后按照上面的设计图,排好每个cell里面的子控件,最终如下图所示:
(2)创建一个继承NSObject的类FillFormCellInfo,用这个类来管理FillFormCell.xib中界面上的数据显示。将Fill's Owner设置为FillFormCellInfo,再将4个cell与FillFormCellInfo关联起来,如下:
@interface FillFormCellInfo : NSObject@property (strong, nonatomic) IBOutlet UITableViewCell *typeCell;@property (strong, nonatomic) IBOutlet UITableViewCell *reasonCell;@property (strong, nonatomic) IBOutlet UITableViewCell *timeCell;@property (strong, nonatomic) IBOutlet UITableViewCell *phoneCell;@end
(3)在FillFormCellInfo中添加加载xib的方法:
- (void)loadCells{ [[NSBundle mainBundle]loadNibNamed:@"FillFormCell" owner:self options:nil];}
这里我想说一下我一直存在的一种误解,我以为FillFormCellInfo中的每一个cell到要用[[[NSBundle mainBundle] loadNibNamed:@"FillFormCell" owner:self options:nil]objectAtIndex:i]赋值一次才可以,于是我愚蠢的写了下面这样的代码:
- (UITableViewCell *)typeCell{ if (_typeCell!=nil) { return _typeCell; } _typeCell = [[[NSBundle mainBundle]loadNibNamed:kXIBName owner:self options:nil] objectAtIndex:0]; return _typeCell;}
其实只要执行了一次[[NSBundle mainBundle] loadNibNamed:@"FillFormCell" owner:self options:nil]就会把所有左侧的控件都返回,也就是FillFormCellInfo中的cell就都不为nil了。如果只是简单的这样初始化还没有问题,但是要在这个初始化方法中做事情可能就会得到错误的结果,你可能会把代码写在loadNibNamed的下面,这样你的代码很可能不会执行了。
(4)在FillFormCellInfo中添加返回高度的方法,我把它写成了一个类方法:
+ (float)heightForRow:(NSIndexPath *)indexPath{ if (indexPath.section == 1) { return 88.f; } return 44.f;}
(5)创建一个继承UIViewController的类RootViewController,添加一个UITableView的全局变量,然后创建界面:
- (void)loadView{ self.view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, kMainFrameWidth, kMainFrameHeight)]; self.view.backgroundColor = UIColorFromRGB(0xf4f4f4); float height = 44*5+10*4+64; _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, kMainFrameWidth, height) style:UITableViewStylePlain]; _tableView.delegate = self; _tableView.dataSource = self; _tableView.separatorStyle = UITableViewCellSelectionStyleNone; _tableView.bounces = NO; [self.view addSubview:_tableView]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.backgroundColor = [UIColor lightGrayColor]; [button setTitle:@"提交" forState:UIControlStateNormal]; button.frame = CGRectMake(10, CGRectGetMaxY(_tableView.frame)+15.f, CGRectGetWidth(self.view.frame)-20, 40.f); [self.view addSubview:button]; [button addTarget:self action:@selector(submitAction:) forControlEvents:UIControlEventTouchUpInside];}
这里tableview的高度我写了死数据,这个数据也可以在FillFormCellInfo中返回。
(6)在RootViewController中添加一个全局变量FillFormCellInfo,在init中进行初始化,然后实现UITableView的delegate和datasource:
#pragma mark - UITableview delegate and datasource- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 4;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 1;}- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 10.f;}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return [FillFormCellInfo heightForRow:indexPath];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //对于这样的每行cell都不一样的,无需整体刷新,所以也不会存在tableview重用时导致的叠加现象,所以不用弄cellIdentifier,用一个cellInfo包含了所有的cell,在其他任何地方都可以改变cell上的内容,无需刷新 [_fillFormCellInfo loadCells]; if (indexPath.section == 0) { return _fillFormCellInfo.typeCell; } else if (indexPath.section == 1){ return _fillFormCellInfo.timeCell; } else if (indexPath.section == 3){ return _fillFormCellInfo.reasonCell; } else if (indexPath.section == 2){ return _fillFormCellInfo.phoneCell; } return nil;}- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES];}
(7)给cell的右侧赋值,以表单类型的cell为例,在FillFormCellInfo.h中添加一个属性:
@property (strong, nonatomic) NSString *leaveFormType;
在typeCell中将右侧的label的tag设置为100,以便拿到这个label,重写leaveFormType的set方法:
- (void)setLeaveFormType:(NSString *)leaveFormType{ if (leaveFormType == nil || [leaveFormType isEqualToString:@""]) { leaveFormType = @"未选择"; } UILabel *label = (UILabel *)[self.typeCell.contentView viewWithTag:100]; label.text = leaveFormType; _leaveFormType = leaveFormType;}
如此,拿到type的值也就容易了。
大致的过程就完成了,完整的代码在这github,总结一下这样做的优缺点:
优点:
1、不用再给cell右侧赋值后重新刷新一次UITableView。
2、很容易拿到每一行Cell的值。
3、View与Model与controller完全剥离开了,没有耦合在一起,也无需在controller去动cell里的控件,这样这些UITableViewCell就能够复用到其他界面了。
缺点:
把每个UITableViewCell都当作全局变量保存起来了,如果cell多时会比较消耗内存。
您如果还有什么方法,也来说一下大致思路哟^_^
- 同一界面加载不同的UITableViewCell,如表单或者设置界面
- 关于登陆或者注册界面EditText的设置
- iOS 调到设置界面 或者app设置界面
- matlib同一界面中不同控件之间的数据传递机制
- 同一表单提交到不同的页面
- 同一表单提交的到不同页
- Android 打开设置界面或者WiFi连接界面
- 利用dll来动态加载不同界面
- 同一表单不同提交
- 同一界面多手势识别的问题
- Android 加载成功、加载失败、加载中、无数据四个不同界面的切换
- 设置加载失败,正在加载,界面。
- Qt同一程序下不同类(不同界面、多个界面)之前同步变量方案
- 打开表单界面的方法
- 界面自适应不同的分辨率
- glide 加载同一路径的不同图片
- Android的设置界面
- 同一表单不同按钮提交到不同的页面
- UVA - 812 Trade on Verweggistan
- 第一个Polymer应用 - (3)使用数据绑定
- 2.3Test
- MASM8.0 下载安装方法
- 新一代视频编码
- 同一界面加载不同的UITableViewCell,如表单或者设置界面
- hdu1348 凸包 用了kuangbin的模板.自己做的
- JSP技术大全 读书笔记(一)
- 怎样用adb抓取log?
- UVA620- Cellular Structure
- 获取局域网内的smsblserver主机的IP地址代码
- Java NIO原理图文分析及代码实现
- Linux-C: const char*如何赋值
- 【POJ】The Bottom of a Graph 强连通