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

一、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 无法显示的解决办法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容