美文网首页好东西小知识点iOS Developer
tableView中一些常用的方法以及一些常见问题

tableView中一些常用的方法以及一些常见问题

作者: 快乐的tomato | 来源:发表于2017-08-29 09:17 被阅读66次

    一、cell的重用机制

    1、why
    同样的cell会被创建很多次,这样很浪费系统的内存,既然是一样的,就可以拿来重复利用
    2、what
    当滚动列表时,部分UITableViewCell会移出窗口,这部分cell放到一个缓存池中,等待重用。

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
       
         //1、定义一个cell的标识   补充:static关键字:使变量成为静态的局部变量,即编译时就为变量分配内存,直到程序退出才释放存储单元,只在本文件内部有效,而其他文件不可连接或引用该变量。
         static NSString *identifier = @"cell";
         // 2、从缓存池中取出cell
         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
         // 3、如果缓存池中没有cell
         if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
         }
         //4、设置cell的数据
         cell.textLabel.text = @"哈哈";
         return cell;
    }
    

    一、刷新

    
    1、全部刷新
     [self.tableView reloadData];//刷新数据
    2、刷新某一个cell
    NSIndexPath *indexPath=[NSIndexPath indexPathForRow:3 inSection:0];
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
    3、刷新某一个section
       NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:section];  
       [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic]; 
    

    二、获取某个指定的cell

     IndexFirstTableViewCell *firstcell = (IndexFirstTableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
        firstcell.firstview.addressLabel.text = @"获取指定的cell";
    

    三、cell的加载方式

    3.1、系统自带的

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
       
         //1、定义一个cell的标识
         static NSString *identifier = @"cell";
         // 2、从缓存池中取出cell
         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
         // 3、如果缓存池中没有cell
         if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;//cell的点击无效果
         }
         cell.textLabel.text = @"哈哈";
         return cell;
    }
    

    3.2、自定义方式(纯代码)
    自定义的cell
    .h文件

    #import <UIKit/UIKit.h>
    
    @class CustomModel;
    
    @interface CustomTableViewCell : UITableViewCell
    @property (nonatomic , strong) CustomModel *model;
    @end
    

    .m文件

    #import "CustomTableViewCell.h"
    #import "CustomModel.h"
    @implementation CustomTableViewCell
    /**
     *  构造方法(在初始化对象的时候会调用)
     *  一般在这个方法中添加需要显示的子控件
     */
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            // 让自定义Cell和系统的cell一样, 一创建出来就拥有一些子控件提供给我们使用
            self.backgroundColor = [UIColor redColor];
            
        }
        return self;
    }
    
    -(void)setModel:(CustomModel *)model{
    
        _model = model;
        
        // 1.给子控件赋值数据
        [self settingData];
        // 2.设置frame
        [self settingFrame];
    }
    /**
     *  设置子控件的数据
     */
    - (void)settingData
    {
    }
    /**
     *  设置子控件的frame
     */
    - (void)settingFrame
    {
    }
    @end
    
    

    ViewController

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
         static NSString *identifier = @"cell";
         // 1.取缓存中取
         CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
         // 2.创建cell
         if (cell == nil) {
            cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;//cell的点击无效果
         }
        cell.model = self.dataArray[indexPath.row];
         return cell;
    }
    

    VC的中的cell再次简化
    CustomTableViewCell.h文件

    #import <UIKit/UIKit.h>
    
    @class CustomModel;
    
    @interface CustomTableViewCell : UITableViewCell
    @property (nonatomic , strong) CustomModel *model;
    + (instancetype)cellWithTableView:(UITableView *)tableView;
    @end
    

    CustomTableViewCell.m文件

    #import "CustomTableViewCell.h"
    #import "CustomModel.h"
    @implementation CustomTableViewCell
    
    + (instancetype)cellWithTableView:(UITableView *)tableView
    {
        static NSString *ID = @"status";
        CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        if (cell == nil) {
            cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        return cell;
    }
    
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            
            // 让自定义Cell和系统的cell一样, 一创建出来就拥有一些子控件提供给我们使用
            
            self.backgroundColor = [UIColor redColor];
    
        }
        return self;
    }
    
    @end
    

    ViewController

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        CustomTableViewCell *cell = [ CustomTableViewCell cellWithTableView:tableView];
        //传递模型
        return cell;
    }
    

    3.2、自定义方式(加载Xib)
    其他都一样,就是加载的时候用 cell = [[[NSBundle mainBundle] loadNibNamed:@" CustomTableViewCell" owner:nil options:nil] firstObject];

    +(instancetype)cellWithTableView:(UITableView *)tableView
    {
        static NSString *identifier = @"tg";
        // 1.取缓存中取
       CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
        // 2.创建cell
        if (cell == nil) {
            // cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
            // 如果找不到就从xib中创建cell
            cell =  [[[NSBundle mainBundle] loadNibNamed:@" CustomTableViewCell" owner:nil options:nil] firstObject];
        }
        return cell;
    }
    

    四、cell中的子控件重叠的解决办法

    1、  [_titleLabel removeFromSuperview];//先移除再加载
      
    2、  [self.backScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];//移除原来的子控件
        [self.backScrollView.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
    
    

    五、计算cell中文字的高度

    /**
     *  计算文本的宽高
     *
     *  @param str     需要计算的文本
     *  @param font    文本显示的字体
     *  @param maxSize 文本显示的范围
     *
     *  @return 文本占用的真实宽高
     */
    - (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize
    {
        NSDictionary *dict = @{NSFontAttributeName : font};
        // 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围
        // 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围
        CGSize size =  [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size;
        return size;
    }
    //调用
      CGSize nameSize = [self sizeWithString:_weibo.name font:[UIFont systemFontOfSize:15] maxSize:CGSizeMake(MAXFLOAT, 屏幕宽度-间隔)];
    
        CGFloat nameLabelH = nameSize.height;
        CGFloat nameLabelW = nameSize.width;
        CGFloat nameLabelY = iconViewY + (iconViewH - nameLabelH) * 0.5;
        self.nameLabel.frame = CGRectMake(nameLabelX, nameLabelY, nameLabelW, nameLabelH);
    

    五、抽取frame模型来计算cell的高度

    如果cell的高度是固定的,那么最方便的方法就是用xib加载的方法,由于我们做的大多数项目的cell的高度都不是固定,图片高度不一定,文字的高度也不一定。所以要抽取一个frame模型来专门计算每个cell的高度。
    步骤:

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

    demo链接

    六、tableView展示数据的过程

    调用数据源的下面方法得知一共有多少组数据
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
    
    调用数据源的下面方法得知每一组有多少行数据
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
    
    调用数据源的下面方法得知每一行显示什么内容
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    
    

    七、cell中的常见问题

    1、cell中的detailTextLabel 无法显示的解决办法

    相关文章

      网友评论

        本文标题:tableView中一些常用的方法以及一些常见问题

        本文链接:https://www.haomeiwen.com/subject/xuandxtx.html