UItableView(重点:xib封装view)

来源:互联网 发布:方舟生存进化优化mod 编辑:程序博客网 时间:2024/06/08 14:49

一.xib封装View,并放到cell上

1.新建一个xib文件描述一个view的内部结构(假设叫做FootView.xib),代码如下.

这里写图片描述
这里写图片描述

2.新建一个自定义的类
(自定义类需要继承自系统自带的view, 继承自哪个类, 取决于xib根对象的Class),新建类的类名最好跟xib的文件名保持一致(比如类名就叫做FootView).
这里写图片描述
3.将xib中的控件 和 自定义类的.m文件 进行连线.
这里写图片描述

5.在FootView类,提供一个类方法返回一个创建好的自定义view(屏蔽从xib加载的过程).

+ (instancetype)footViews;+ (instancetype)footViews{    return [[[NSBundle mainBundle] loadNibNamed:@"FootView" owner:nil options:nil]lastObject];}

6.添加到自己定义的tableView的footView上,在控制中调用.

  /**1.第一种方法,xib加载view,设置footView*/    FootView *footView = [FootView footView]; /**2.添加到自定义的footView上*/    self.myTableView.tableFooterView = footView;

二.在cell上加载更多数据

1.往cell中添加更多数据,这就是改变数据模型,对存储数据模型的数组做操作,最后刷新表单.2.事例,在footView里有一个按钮,当点击了按钮以后,控制器更新tableView里的数据,代码如下:    1.1创建代理,向控制器传递一个方法,后面参数带上自己类的名字,这样控制器才知道是谁的方法.
#import <UIKit/UIKit.h>@class FootView;/**1.创建协议,为了规范协议必须是自己的类名开始*/@protocol footViewDelegate <NSObject>/**2.协议里的方法,类名+完成单击后,然后再传入自己的类名,这样别的类才知道是谁的方法,代表选择实现@optional*/@optional- (void)footViewDidClickBtn:(FootView *)footView;@end@interface FootView : UIView+ (instancetype)footView;/**3.设置代理人*/@property (weak, nonatomic) id<footViewDelegate>delegate;@end
1.2在xib中创建一个按钮,然后连线

这里写图片描述
,首先把view隐藏了,也就是在右边的hidden打上对号.

/**1.按钮属性*/@property (strong, nonatomic) IBOutlet UIButton *myButton;/**2.按钮点击事件*/- (IBAction)btn;/**3.按钮点击事件的实现*//**1.按钮隐藏*/    self.myButton.hidden = YES;/**2.view显示*/    self.myView.hidden = NO;/**3.用GCD作延时操作,1.0代表延时1秒*/    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ /**4.加载更多,调用代理方法*/        if ([self.delegate respondsToSelector:@selector(footViewDidClickBtn:)]) {            [self.delegate footViewDidClickBtn:self];        }/**5.隐藏view*/        self.myView.hidden = YES;/**6.显示按钮*/        self.myButton.hidden = NO;     });
 2.在控制器中采用协议,将footView的代理设置成控制器,即self,并实现协议里的方法,代码如下;
/**1.采用协议*/@interface ViewController ()<footViewDelegate>/**2.设置代理*//**2.1.xib加载view,设置footView*/    FootView *footView = [FootView footView];/**2.2.设置代理*/    footView.delegate = self;/**2.3.添加上自定义tableView的tableFooterView上*/    self.myTableView.tableFooterView = footView;/**3.实现代理的方法,添加更多数据*/#warning 正常开发:发送网络语法给远程的服务器(这里是假数据用做模拟)- (void)footViewDidClickBtn:(FootView *)footView{  /**1.创建数据模型*/    TagsModel *tags = [[TagsModel alloc] init];  /**2.给数据模型的元素增加数据*/    tags.icon = @"2010e3a0c7f88c3f5f5803bf66addd93.png";    tags.title = @"好地方";    tags.price = @"免费";    tags.buyCount = @"20";  /**3.加到数组中*/     [self.array addObject:tags];  /**4.刷新tableView数据*/    [self.myTableView reloadData];}

三.cell简单属性

     1.UITableView的每一行都是一个UITableViewCell,通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行2.UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图3.辅助指示视图的作用是显示一个表示动作的图标,可以通过设置UITableViewCell的accessoryType来显示,默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:
    3.1 UITableViewCellAccessoryDisclosureIndicator    3.2 UITableViewCellAccessoryDetailDisclosureButton    3.3 UITableViewCellAccessoryCheckmark(向右箭头)    3.4 还可以通过cell的accessoryView属性来自定义辅助指示视图(比如往右边放一个开关).

三.cell的复用

1.为什么要cell的复用:iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象

2.重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象.
3.还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell,所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell

解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{/**1.定义一个cell的标识*/      static NSString *ID = @"cell";/** 2.从缓存池中取出cell*/      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];/**3.如果缓存池中没有cell*/      if (cell == nil) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];    } /**4.设置cell的属性...*/      return cell;}

四.通过代码自定义cell(cell高度不一致时)

1.新建一个继承自UITableViewCell的类2.重写initWithStyle:reuseIdentifier:方法添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中)进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)3.提供2个模型数据模型: 存放文字数据\图片数据frame模型: 存放数据模型\所有子控件的frame\cell的高度4.cell拥有一个frame模型(不要直接拥有数据模型)5.重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)
0 0
原创粉丝点击