免费开源的iOS开发学习平台

UITableView详解:10-自定义Cell

系统自带的单元格UITableViewCell类,可以提供4种样式,在实际的App开发中,绝大多数情况下,都需要对单元格的样式进行定制,因此必须要掌握如何实现自定义单元格。根据MVC的设计模式要求,单元格属于视图View的范畴,我们需要创建一个UITableViewCell类的子类,来进行定制单元格的样式定制。

案例分析

在本节中我们将仿照新浪微博中单元格样式做一个简单的案例。

我们对上述单元格的样式进行分析可以得到如下结论:在这个界面中有2个UIImageView控件和3个UILabel控件,我们需要把这5个子控件添加到一个UITableViewCell上。

创建自定义单元格类

创建一个继承自UITableViewCell类的子类MYTableViewCell,并添加一个类方法,便于创建自定义Cell的对象;

@interface MYTableViewCell : UITableViewCell
+(instancetype) cellWithTableView:(UITableView *)tableview;
@end

简便期间,我们创建一个xib文件,命名为MYTableViewCell.xib,用来定制单元格的样式,在单元格中,添加2个UIImageView控件以及3各UILabel控件,并调整这些子控件的位置和大小;

在MYTableViewCell.m文件中,实现创建自定义单元格对象的方法。

+(instancetype) cellWithTableView:(UITableView *)tableview {
    static NSString *cellID = @"cell";
    MYTableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        //IB中创建cell
        cell = [[[NSBundle mainBundle] loadNibNamed:@"MYTableViewCell" owner:self options:nil] lastObject];
    }
    return cell;
}

创建单元格对应的数据模型

iOS开发中遵循MVC模式,在这里我们创建一个数据模型类MYModel类,继承自NSObject,通过该类来为MYTableViewCell对象提供显示的数据。在MYModel.h文件中,设置模型的属性并声明一个用于初始化的类方法。

@property (nonatomic,copy) NSString *profileImageName;//头像
@property (nonatomic,copy) NSString *userName;//发送用户
@property (nonatomic,copy) NSString *source;//设备来源
@property (nonatomic,copy) NSString *content;//内容
@property (nonatomic,copy) NSString *iconName;//小图标
+(instancetype)myCellModel;

在MYModel.m文件中,实现类方法。简单期间,我们为创建的MYModel类的对象属性提供统一的默认值。

+(instancetype)myCellModel {
    MYModel *cellModel = [[MYModel alloc]init];    
    cellModel.userName = @"99iOS";
    cellModel.profileImageName = @"99logo";
    cellModel.iconName = @"99logo";
    cellModel.source = @"来自99的iPhone 7 Plus";
    cellModel.content = @"苹果iOS开发进阶之路";
    return cellModel;
}

在MYTableViewCell.h文件中导入数据模型头文件, 并添加一个MYModel类的属性,用于接收控制器传递的数据;

@property(nonatomic,strong) MYModel *cellData;

在MYTableViewCell.m文件中重写该属性的setter方法,给单元格中的控件设置数据。(我们需要预先为MYTableViewCell.xib中的控件建立属性连线)

- (void)setCellData:(MYModel *)cellData {
    _cellData = cellData;
    self.profileImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",cellData.profileImageName]];
    self.userNameLabel.text = cellData.userName;
    self.sourceLabel.text = cellData.source;
    self.iconImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",cellData.iconName]];
    self.contentLabel.text = cellData.content;
}

在表视图的数据源方法中使用自定义单元格

在表视图的数据源方法cellForRowAtIndexPath:中,按照4步完成单元格的设置:

  • 初始化MYTableViewCell类型的单元格;
  • 获取MYModel类型的数据;
  • 把MYModel类型的数据传递给单元格;
  • 返回单元格对象。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MYTableViewCell *cell = [MYTableViewCell cellWithTableView:tableView];
    MYModel * cellData = self.rowDataArray[indexPath.row];
    cell.cellData = cellData;
    return cell;
}

另外,在运行程序之前,不要忘记导入数据模型文件和自定义单元格的头文件,同时在初始化tableview时要根据xib中的cell高度,设置tableview的rowHeight值,否则cell的内容会重叠。运行效果如下(为了能清楚地看到子控件的分布,设置了背景色和边框)。

示例代码

https://github.com/99ios/8.2.10