UITableView

1. UITableView展示表格数据

特征:

  1. 继承自UIScrollView,可以滚动.
  2. 含常规代理和数据源代理(dataSource)来监听操作.

属性:

  1. 含两种展示样式:根据sections数决定.
    • UITableViewStylePlain 单组显示
    • UITableViewStyleGrouped 多组显示.
  2. 三个基本数据:从遵守数据源协议的控制器中实现协议方法来获取.(必须实现的)
    • 多少组(section)- (NSInteger)numberOfSection…
      • 每组多少行(Row): -(NSInteger) tableView: numberOfRowInSection….
    • 每行显示什么样的cell:-(UITableView*)tableView: cellForRowsInSection:..
      1. 其中系统cell
        • 自动包含了imageView,textLabel,detailTextLabel,accessoryType四个属性,都是只读的,所以只能修改其子控件属性,这四个属性不是直接放在cell上,而是在ContentView上.
        • 剩下的还有背景色与背景View,选中状态背景色与View,View优先级较高.
        • cell行高设置:两种方式,
        • 整体:self.tableView.rowHeight.
        • 用代理局部设置:- (CGFloat)tableView heightForRowAtIndexPath:
      2. 可以单独设置每组的头部和尾部,-(NSString*)tableView: titleForHeaderInSection:.
      3. 分割线.设置方式:
        • 设置颜色:self.tableView.separatorColor = UIColor.
        • 设置样式:self.tableView.separatorStyle = ….;
      4. 设置总得头尾,这个头尾是UIView类型,所以所有的UIView子控件都能赋值做头尾.
        • 例:self.tableView.tableHeaderView = [[UIButton alloc] init];

UITableViewCell.

作为UITableView中最重要的组成.
tableView的性能优化—————–(面试题)
问题:每次拖动tableView都要新建销毁cell,如何解决.
解决方式:
cell的重用,把要销毁的存入tableView的缓存池,需要显示新的时候,不创建,而是通过设置的ID来找到修改之前的.

在数据源第三方法中的第二部分创建cell中:
static NSString *ID = @"任意字符串";
//通过ID找出cell,queue:出列,
UITableViewCell *cell = [tableView dequeueReusableCellWithIndentifier:ID];
//判断,如果没找到
if(cell == nil){
    cell = [[ITableView alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}

cell重用问题:
重用时,有的cell有配图,有的没配图,重用的时候,本来没配图的不会重置刷新配图的这个属性,这样,就会出现配图.
解决:设置配图属性时加个判断.
重用可以封装cell init中
cell的自定义:
有时候系统cell无法满足多样的格式,需要我们自定义或xib创建方法.
思路:

  1. 自定义继承UItableViewCell的类型文件,并新建同名xib文件.
  2. xib文件中设置UI布局,连线到类型文件中根据数据进行赋值.(为了安全,连线到类扩展中),cell重用可以封装到.m文件中.

引申的:
多个xib之间如何联系:例如点击xib1的按钮,会操作xib2的控件:
思路:

  • 通过控制器代理.
  • xib1建立代理需求,新增协议声明方法,
  • 控制器设置自己为xib1代理,重写声明方法,在方法中修改记录的数据,然后传给xib2,在刷新xib2,即可.
  • 简易的MVC思想.
  • 注意:行数变化,即cell数变化时,不能用单独刷新(原理是先删除再添加),用全部刷新或添加方法.在xib类型文件中有类型ViewDidLoad的方法awakeFromNib,在加载xib完毕时自动调用,可用于纯代码创建一些空间.

引申的:
由于xib文件虽然适于多个同规格cell设置,但是每个cell规格固定了,对于需要每个Cell随情况而变,则需要完全的纯代码创建.
步骤:

  1. 需要自定义控制器,继承UITableViewController,这个自带UITableView属性.
  2. 自定义cell视图文件,继承UITableViewCell.
  3. 重写cell的工厂方法:(在其中设置固定的属性,不固定的留在set方法中获取数据重写)

    例:

    • (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *) reuseIdentifier; {
      if (self = super initWithS….. ) {
      //创建子控件
      UIImageView *imageViewIcon =[[UIImageView alloc ]ini];
      //添加到cell
      self.contentView addSubview:imageViewIcon //注意不要跟继承的ImageView重名了.
      //设置属性三部曲:
      设置不变的,变化的在set方法获取数据来设置.(set调用多此,如果固定的也设在里面,浪费性能.)
  4. 控制器中仍旧懒加载(模型嵌套加一步赋值)->数据源方法(第三个cell中需要创建自定义cell,传进去数据)->代理方法->设置下头尾行高等.

面试题
为什么引入frame模型:
由于cell行高设置方法优先级高于数据源第三方法优先级,这使的我们行高设置所需数据没有获取到就开始设置.错误的.

因此,我们需要跟之前一样先获取到数据,那么我们以前数据怎么先获得的–懒加载.
步骤:

  1. 引入frame模型,存储要计算的frame数据(readonly).通过重写set方法来计算,那么数据来源呢.所以,还需要设置一个模式属性来接受数据.就是模型嵌套了.
  2. 在控制器的懒加载中,先加载文件数据模型中,再赋值给frame中的同类型模型,之后控制器的数据就用frame即可,(frame的set数据方法重写了,那么赋回给控制器的就增加了计算后的frame值,最后在创建cell时传进去即可),(类似蛇进水中,乌龟出来了.)

    对于固定cell可以在UI里面快速设置静态单元格.
    也可以使用cell模板(cell的注册机制):

  3. storyBoard中给cell设置ID或者代码self.tableView register...来注册.之后在控制器中用ID来创建UItableViewCell *cell = [tableView dequeue...]此时会先在缓存池中需寻找,找不到就会进storyboard需找对应ID.所以不同cell模板的id不能相同.这样可以省很多xib文件.可以在一个tableview中设置很多格式cell,设置不同id,用的时候找id即可.

  4. 之后自定义类关联连线,传入数据,设置控件属性即可.注意下,cell的行高只能在代码中设置.
  5. cell的注册机制.
    • 现充缓存池

tableView中每一组的headerView和FootView-宽度都是永远不变的,不用设置.
头尾部的数据源代理方法:

titleForHeaderInSection//返回头部title
ViewForHeaderInSection//返回头部view
heightForHeaderInSection //设置 某一行头部高度. 
  1. 界面图片大小与控制器关系:当图片小于控制器大小时,控制器会调节到图片大??
  2. 数据文件是字典嵌套时,不含字典的才能用KVC,嵌套部分用老办法循环遍历.最后模型数据也是嵌套的.过程封装进外层模型的工厂方法.
  3. 修改tableView的Cell时,需要(刷新)才能显示,可调用代理选中操作时的方法,在代理方法中进行刷新.
  4. 开发文件的MVC方式分类.
  5. 计算行高两种方式:调用字符串方法 bound…..计算一堆文字的高和和宽.//另一种是UIview的方法,设置 自动缩放到内部内容的大小.推荐字符串方法.

你可能感兴趣的:(UITableView)