iOS 自定義不等高的cell

自定義不等高的cell


1.給模型增加frame數(shù)據(jù)(純代碼)

  • 讓ViewController繼承UITableViewController,移除storyboard中的ViewController,新建一個UITableViewController讓其與ViewController建立關(guān)聯(lián)。

    @interface ViewController:UITableViewController

  • 在ViewController.m文件中實現(xiàn)UITableView代理的這個方法,這個方法會返回cell的高度,所以需要在返回高度前計算出cell的高度。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    AZStatus *status=self.statuses[indexPath.row];
    
    return status.cellHeight;
}
  • 在status數(shù)據(jù)模型中計算出所有控件frame,只有模型數(shù)據(jù)知道哪些控件需要顯示,這個方法會經(jīng)常調(diào)用,考慮到性能對其進行判斷,只有當?shù)谝淮握{(diào)用時才會計算。
- (CGFloat)cellHeight
{
    
    if (_cellHeight==0) {
        CGFloat margin=10;
        ...
        // 圖片frame
        if (self.picture) {//有配圖
            CGFloat picX=margin*3;
            CGFloat picY=CGRectGetMaxY(self.textFrame)+margin;
            CGFloat picWH=200;
            self.pictureFrame=CGRectMake(picX, picY, picWH, picWH);
            _cellHeight=CGRectGetMaxY(self.pictureFrame)+margin;
        }else{//無配圖
            
            _cellHeight=CGRectGetMaxY(self.textFrame)+margin;
        }

    }
    
    return _cellHeight;
}

  • 添加控件
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        ...
        
        //配圖
        UIImageView *pictureView=[[UIImageView alloc]init];
        [self.contentView addSubview:pictureView];
        self.picture1View=pictureView;  
        
    }
    
  • 在AZStatusCell.h文件中引用模型
#import <UIKit/UIKit.h>
@class AZStatus;
@interface AZStatusCell : UITableViewCell

/*模型數(shù)據(jù)*/
@property(nonatomic,strong)AZStatus *status;

@end
  • 在模型的set方法中給控件注入數(shù)據(jù),同時也可以確定frame,和在layoutSubViews中確定frame效果一致

-(void)setStatus:(AZStatus *)status
{
    _status=status;
    // 設置數(shù)據(jù)
    ...
    // 配圖
    if (status.picture) {
        self.picture1View.hidden=NO;
        self.picture1View.image=[UIImage imageNamed:status.picture];
    }else{
        self.picture1View.hidden=YES;
    }
    
    //設置frame
    self.iconView.frame=status.iconFrame;
    self.nameLabel.frame=status.nameFrame;
    self.text_Label.frame=status.textFrame;
    self.vipView.frame=status.vipFrame;
    self.picture1View.frame=status.pictureFrame;
     
}

2.storyboard動態(tài)cell實現(xiàn)(iOS8以后)

  • 在stroyboard的動態(tài)cell中添加所有的子控件
  • 將cell中所有的子控件和AZStatusCell.m文件中的屬性建立好連線,并將圖片的約束也建立好連線


  • 在status模型的set方法中,通過圖片高度的約束控制圖片顯示與隱藏,上方間隙的約束的調(diào)整來控制所有cell下方的間隙一致
-(void)setStatus:(AZStatus *)status
{
    _status=status;
    
    // 設置數(shù)據(jù)
    ...    
    // 配圖
    if (status.picture) {
        self.picture1View.hidden=NO;
        self.picture1View.image=[UIImage imageNamed:status.picture];
        self.pictureTop.constant=10;
        self.pictureHeight.constant=100;
        
    }else{
        self.picture1View.hidden=YES;
        self.pictureHeight.constant=0;
        self.pictureTop.constant=0;
    }
    

    
}
  • 設置tableViewCell的真實行高和估算行高
    // self-sizing(iOS8以后,兩個方法一起使用)
    // 設置tableView的高度為根據(jù)設定的約束自動計算
    self.tableView.rowHeight=UITableViewAutomaticDimension;
   
    // 設置tableView的估算高度
    self.tableView.estimatedRowHeight=44;

3.如果要支持iOS8之前

  • 如果cell內(nèi)部有自動換行的label,需要設置preferredMaxLayoutWidth屬性
- (void)awakeFromNib
{
    // 手動設置文字的最大寬度(目的是:讓label知道自己文字的最大寬度,進而能夠計算出自己的frame)
    self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
  • 設置tableView的cell估算高度
// 告訴tableView所有cell的估算高度(設置了估算高度,就可以減少tableView:heightForRowAtIndexPath:方法的調(diào)用次數(shù))
self.tableView.estimatedRowHeight = 200;
  • 在代理方法中計算cell的高度
AZStatusCell *cell;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 創(chuàng)建一個臨時的cell(cell的作用:根據(jù)模型數(shù)據(jù)布局所有的子控件,進而計算出cell的高度)
    if (!cell) {
        cell = [tableView dequeueReusableCellWithIdentifier:ID];
    }

    // 設置模型數(shù)據(jù)
    cell.status = self.statuses[indexPath.row];

    return cell.height;
}

- (CGFloat)height
{
    // 強制布局cell內(nèi)部的所有子控件(label根據(jù)文字多少計算出自己最真實的尺寸)
    [self layoutIfNeeded];

    // 計算cell的高度
    if (self.status.picture) {
        return CGRectGetMaxY(self.pictureImageView.frame) + 10;
    } else {
        return CGRectGetMaxY(self.text_label.frame) + 10;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容