1. 程式人生 > >OC中UITableView之自定義cell的使用(2):通過程式碼建立

OC中UITableView之自定義cell的使用(2):通過程式碼建立

在使用UITableView做開發時,常常會遇到 系統提供的樣式無法滿足專案需求的情況,這時就需要根據需求來自定義cell。

自定義cell有兩種方式:

  · 通過xib自定義cell(適用於cell中子控制元件個數固定、cell樣式統一的結構,例如:商品的列表頁面)

  · 通過程式碼自定義cell(適用於cell中子控制元件個數不固定、cell樣式不統一的結構,例如:微博列表)

通過程式碼建立自定義cell:

1.新建一個繼承自UITableViewCell的類

2.先在構造方法initWithStyle: reuseIdentifier:

  ·新增所有需要顯示的子控制元件(不需要設定資料和frame,子控制元件要新增到contentView中)

  ·進行子控制元件一次性的屬性設定(有些屬性只需要設定一次 例如:字型、固定的圖片等)

/**
 構造方法在建立物件時呼叫
 一般在這個方法中新增需要使用的子控制元件
 */
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //1.頭像
        UIImageView *iconView = [[UIImageView alloc] init];
        self.iconView = iconView;
        [self.contentView addSubview:iconView];
        //2.暱稱
        UILabel *nameView = [[UILabel alloc] init];
        nameView.font = NameFont;
        [self.contentView addSubview:nameView];
        self.nameView = nameView;
        
        //3.會員圖示
        UIImageView *vipView = [[UIImageView alloc] init];
        vipView.image = [UIImage imageNamed:@"vip"];
        [self.contentView addSubview:vipView];
        self.vipView = vipView;
        
        //4.正文
        UILabel *textView = [[UILabel alloc] init];
        textView.numberOfLines = 0;
        textView.font = TextFont;
        [self.contentView addSubview:textView];
        self.textView = textView;
        
        //5.配圖
        UIImageView *pictureView = [[UIImageView alloc] init];
        [self.contentView addSubview:pictureView];
        self.pictureView = pictureView;
    }
    return self;
}

3.提供2個模型

  ·資料模型:存放文字、圖片等資料

        重寫構造方法:通過字典初始化物件

+(instancetype)statusWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}

-(instancetype)initWithDict:(NSDictionary *)dict
{
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}

  ·frame模型:存放資料模型,存放所有子控制元件的frame資料和 cell 的最終高度

4.cell擁有一個frame模型屬性(不要直接擁有資料模型,frame模型中包括資料模型和frame資料)

5.重寫frame模型屬性的setter,在這個方法中設定子控制元件的資料和frame

- (void)setStatus:(Status *)status
{
    //設定資料模型資料
    _status = status;
    
    //計運算元控制元件的frame
    //子控制元件之間的間距
    CGFloat padding = 10;
    //1.頭像
    CGFloat iconX = padding;
    CGFloat iconY = padding;
    CGFloat iconH = 35;
    CGFloat iconW = 35;
    _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
}

6.frame模型資料的初始化,通過懶載入的方式(每一個cell對應的frame模型只加載一次)

    控制器中擁有一個frame模型屬性

/**
懶載入資料
 */
-(NSArray *)statusesFrame
{
    if (_statusesFrame == nil) {
        //初始化資料
        NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *statusFrameArray = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            //建立status模型
            Status *status = [Status statusWithDict:dict];
            //建立statusFrame模型
            StatusFrame *statusFrame = [[StatusFrame alloc] init];
            statusFrame.status = status;

            [statusFrameArray addObject:statusFrame];
        }
        _statusesFrame = statusFrameArray;
    }
    return _statusesFrame;
}

7.實現TableView的資料來源方法

/**
 資料有多少行
 */
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.statusesFrame.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1.建立cell
    StatusCell *cell = [StatusCell cellWithTableView:tableView];
    //2.傳遞模型資料給cell
    cell.statusFrame = self.statusesFrame[indexPath.row];
    
    return cell;
}

8.實現TableView的代理方法,設定每個cell的高度

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    StatusFrame *statusFrame = self.statusesFrame[indexPath.row];
    
    return statusFrame.cellHeight;
}