IOS - 自定义cell
来源:互联网 发布:黑马校对软件多少钱 编辑:程序博客网 时间:2024/05/29 16:41
因为休假了好几天, 好多东西都忘记了,所以决定写一篇开发过程,找找缺漏........
模拟实现一个团购界面
底部按钮
我们知道tableview 是可以用三部分描述的
tableHeaderView + tableFooterView + cell
我们先实现cell部分, 在此之前先把数据模拟加载.这次详细的复习下数据的模拟加载.
1.数据加载
将数据封装成对象, 然后放到数组中.
我们会在内存中用一个数组来存放数据, 我们希望将数据封装起来, 所以创建一个类, 用来描述所有的数据.
(根据plist文件在类中定义属性, 属性名字最好和plist中的属性名一样,这样我们可以使用KVC的方式读取. 对于源数据封装到plist中, 我们最常见的是每一条记录封装成一个字典项,这样当我们读取的时候可以用KVC的 setValuesForKeysWithDictionary: (NSDictionary *) ; 语句进行读取.)
在类中定义完属性, 还需要定义方法, 用来初始化并从文件中读取数据
- (instancetype)initWithDic:(NSDictionary *)dic;+ (instancetype)groupBuyingWithDic:(NSDictionary *)dic; //用类方法, 直接返回用字典转换为模型的对象.
+ (NSMutableArray *)groupBuyingsList;实现:
- (instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { [self setValuesForKeysWithDictionary:dic]; //读取数据 } return self;}+ (instancetype)groupBuyingWithDic:(NSDictionary *)dic{ return [[self alloc] initWithDic:dic]; }+ (NSMutableArray *)groupBuyingsList //将封装好的对象 加载到数组中, 返回给内存中模拟的数组{ //加载plist NSString *path = [[NSBundle mainBundle] pathForResource:@"tgs" ofType:@"plist"]; NSArray *dicArray = [NSArray arrayWithContentsOfFile:path]; //字典转模型 NSMutableArray *tmpArray = [NSMutableArray array]; //将要返回给内存中的数组 for (NSDictionary *dic in dicArray) { CZGroupBuying *groupBuying = [CZGroupBuying groupBuyingWithDic:dic]; [tmpArray addObject:groupBuying]; } return tmpArray;}
当我们的字典项中还嵌套了数组, 数组又嵌套了字典的时候 ,我们需要两次转换..
比如这种..
+ (NSArray *) carGroupsList{ NSString * path = [[NSBundle mainBundle] pathForResource: @"cars_total" ofType: @"plist"]; NSArray * dicArray = [NSArray arrayWithContentsOfFile: path]; NSMutableArray * tmpArray = [NSMutableArray array]; for (NSDictionary * dic in dicArray) { AMCarGroup * cargroup = [AMCarGroup carGroupWithDic: dic]; NSMutableArray * tmpCarArray = [NSMutableArray array]; for (NSDictionary * tmpdic in cargroup.cars) { //在加一次循环,读取嵌套的字典中的内容... AMcar * car = [AMcar carWithDic: tmpdic]; [tmpCarArray addObject: car]; } cargroup.cars = tmpCarArray; [tmpArray addObject: cargroup]; } return tmpArray;}
由于上面的封装, 所以在给内存中模拟的数组, 加载数据就很简单了...
- (NSMutableArray *)groupBuyings{ if (_groupBuyings ==nil) { _groupBuyings = [CZGroupBuying groupBuyingsList]; } return _groupBuyings;}
2. 自定义cell
大多时候,我们需要进行自定义cell, 所以要用到xib, 在xib中布局好控件后,我们将它封装成类. 并且 这个类是继承 UITableViewCell类的, 这一点很重要.
但是,控件还没有描述信息, 所以我们再在类中添加一个信息的属性.
@class CZGroupBuying;@interface CZGroupBuyingCell : UITableViewCell@property (nonatomic, strong) CZGroupBuying *groupBuying;+ (instancetype)groupBuyingCellWithTableView:(UITableView *)tableView;@end
因为我们已经将描述信息封装成了类,所以我们字需要定义一个对象属性即可.
而我们定义的类方法,是直接从xib中读取控件, 这里需要主要的是, 需要传入一个UITableView * 参数, 因为在创建缓冲池的时候需要用到.
实现:
+ (instancetype)groupBuyingCellWithTableView:(UITableView *)tableView{ static NSString *reuseId = @"gb"; CZGroupBuyingCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId]; if (cell == nil) { cell = [[[NSBundle mainBundle] loadNibNamed:@"CZGroupBuyingCell" owner:nil options:nil] lastObject]; } return cell;}//重写属性的setter方法,给子控件赋值- (void)setGroupBuying:(CZGroupBuying *)groupBuying{ _groupBuying = groupBuying; self.titleView.text = groupBuying.title; self.priceView.text = [NSString stringWithFormat:@"¥ %@",groupBuying.price]; self.buyCountView.text = [NSString stringWithFormat:@"%@人已购买",groupBuying.buyCount]; self.iconView.image = [UIImage imageNamed:groupBuying.icon];}
这里再说明下, 我们将xib中的控件, 封装成的类是继承UITableViewCell类的..然后通过类方法 ,返回xib中读取到的对象(控件).
最后在数据源协议方法中调用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //1 创建可重用的自定义的cell CZGroupBuyingCell *cell = [CZGroupBuyingCell groupBuyingCellWithTableView:tableView]; //2 设置cell内部的子控件 CZGroupBuying *gb = self.groupBuyings[indexPath.row]; cell.groupBuying = gb; //重写的setter方法 //3 返回 return cell;}
3. 创建tableHeaderView
因为tableHeaderView是一个UIView所以可以很随意的使用控件..这里我们用到的是一个scrollView, 正好复习下,所详细说一下...
由于这个头部控件 ,是多个控件所以用xib 组合一下, 最重要的还是scrollView.
当我们在xib中创建好scrollView的时候 ,由于我们需要大量操作他,我们使用最简单的方法, 直接连线解决, 这样就可以得到一个outlet属性...
首先定义xib的实现类, 用类方法返回加载到的控件.因为加载到的控件里面的scrollView需要滚动, 他的滚动时机,需要一个 方法控制
- (void)awakeFromNib{ CGFloat iconW = self.scrollView.frame.size.width; CGFloat iconH = self.scrollView.frame.size.height; for (int i = 0; i < 5; i++) { NSString *imgName = [NSString stringWithFormat:@"ad_%02d",i]; UIImageView *iconView = [[UIImageView alloc] init]; [self.scrollView addSubview:iconView]; iconView.image = [UIImage imageNamed:imgName]; CGFloat iconX = i * iconW; CGFloat iconY = 0; iconView.frame = CGRectMake(iconX, iconY, iconW, iconH); } self.scrollView.contentSize = CGSizeMake(5 * iconW, 0);}
这个函数 是在xib加载完成的时候 触发的..我们只需要实现他即可....
注意这次是代码实现的imageview控件, 需要我们设置imageview的位置
iconView.frame = CGRectMake(iconX, iconY, iconW, iconH);
最后还需要设置 scrollview的滚动范围.
self.scrollView.contentSize = CGSizeMake(5 * iconW, 0);
4. 创建tableFooterView
同样还是xib先实现
这个布局很具有代表性, 首先最外层是一个View, 所有的控件都在这个View中, 然后根据效果, 再点击了加载更多按钮后要显示一个lable..
这样当需要要操作某些控件的时候, 都能清晰的找到其父控件 , 我们只需要对其父控件进行隐藏 或显示 , 就可以不必挨个的对其子控件 设置隐藏或显示...
这想说的是, 我们使用了一个代理 去实现点击按钮后要触发的事件...复习下代理:
1.给相应的类定义代理协议, 并声明 该类还具备的某些能力
@protocol CZFooterViewDelegate <NSObject> //定义协议@optional- (void)footerViewDidClickedLoadMoreBtn:(CZFooterView *)footerView; //具备的能力@end上面的footerViewDidClickedLoadMoreBtn:(CZFooterView *)footerView 参数是一个 czfooterview * 类型的. 这个footerview 参数就是从xib中读取的控件..
2. 在类添加 与 代理 沟通的媒介 (代理属性)
@interface CZFooterView : UIView//2 定义代理属性@property (nonatomic, weak) id<CZFooterViewDelegate> delegate; //代理属性+ (instancetype)footerView;@end
3. 用点击按钮所注册的事件处理方法中, 调用代理属性 去调用协议中的方法
- (IBAction)loadMoreClick { self.loadMoreBtn.hidden = YES; self.loadMoreView.hidden = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.loadMoreBtn.hidden = NO; self.loadMoreView.hidden = YES; //3 向代理对象发送消息 if ([self.delegate respondsToSelector:@selector(footerViewDidClickedLoadMoreBtn:)]) { [self.delegate footerViewDidClickedLoadMoreBtn:self]; } }); }
上面代码中的self 就是xib中所读取到的控件, 因为我们的xib文件的实现类就是CZfooterView, 虽然这个类中没有其他属性, 看似是一个空类, 但是我们仍可以用self 来描述他所产生的对象.
self --------> CZfooterVIew对象.
我们在写方法的时候, 我们是在为对象 写方法...类方法 也是 内部调用了对象的.
再加深下对self 的理解...................
- iOS cell自适应 自定义cell
- iOS 自定义cell
- ios UITableview自定义cell
- IOS学习 Cell自定义
- ios 自定义cell demo
- iOS UI09_自定义cell
- IOS - 自定义cell
- iOS--xib自定义cell
- iOS ---xib自定义cell
- ios 开发自定义cell
- IOS中Cell自定义
- iOS-cell.selectedBackgroundView自定义
- IOS之自定义Cell
- iOS-自定义cell
- iOS 自定义cell
- iOS tableview自定义cell
- IOS UITableView 移动自定义cell
- iOS 自定义Cell 自适应高度
- 线程与进程
- LeetCode 18: 4Sum
- 坐标相关的android应用程序中获取view的位置
- 抽象类与接口
- Spring-data-redis在shiro中的实例
- IOS - 自定义cell
- 虚拟现实大会ChinaVR2015报告之-数据可视化的挑战与机遇
- ORACLE LINUX 6.3 + ORACLE 11.2.0.3 RAC + VBOX安装文档
- Python 正则表达式(分组)
- 电话号码验证
- 处理ios问题“Library not found -lPods-(someCocoapod)”
- 我的第一个JS/CSS程序
- Oracle pl/sql编程 25--调用返回结果集的存储过程
- Hibernate-整体介绍