iOS AutoLayout進階(五)UITableViewCell自動高度

前言

前面幾個章節詳細介紹了Aspect Ratio、Content Hugging Priority(抗拉伸優先級)和Content Compression Resistance Priority(抗壓縮優先級), 本文將綜合運用這些特性,在不計算UITableViewCell高度、不使用第三方自動計算高度框架的前提下,來實現UITableViewCell自動高度.git

一. UITableViewCell自動高度:

iOS8 WWDC 中推出了 self-sizing cell 的概念,旨在讓 cell 本身負責本身的高度計算, 因爲以前APP 須要兼容iOS7,因此不少開發者因爲考慮到兼容iOS7,仍是使用手動計算高度,或第三方自動計算高度框架,來計算動態UITableViewCell高度, 但隨着Xcode9普及,開發工具限制了最低只能兼容到iOS8,因此咱們能夠好好運用這一特性了,沒必要在使用傳統方式來處理動態UITableViewCell高度了.github

二.自動高度Demo效果(此效果模仿悟空問答某一界面)

Demo.gif

三.實現部分

1.UITableView只須要作以下設置
  • 以下:
//cell預估高度,設一個接近cell高度的值
self.tableView.estimatedRowHeight = 100;//也能夠省略不設置,

//設置rowHeight爲UITableViewAutomaticDimension,
self.tableView.rowHeight = UITableViewAutomaticDimension;//能夠省略不設置
複製代碼
  • 不實現UITableView返回cell高度代理方法
/** -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ //不實現 } */
複製代碼
2. AutoLayout部分
  • cell AutoLayout部分添加好各控件約束,並設置好動態高度控件的Content Hugging Priority和Content Compression Resistance Priority優先級便可

四.實際運用

下面咱們一塊兒來看下,在不計算高度的前提下,怎麼實現上面悟空問答界面效果

1.代碼部分

代碼部分很簡單,就一個簡單的UITableView,自定義一個cell,以下:json

#import "ViewController.h"
#import "DemoModel.h"
#import "YYModel.h"
#import "DemoCell.h"

static NSString *const id_DemoCell = @"DemoCell";

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic, strong) NSArray *dataArray;
@property (nonatomic, strong) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.tableView];
    [self.tableView registerNib:[UINib nibWithNibName:id_DemoCell bundle:nil] forCellReuseIdentifier:id_DemoCell];
}

#pragma mark - tableView
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataArray.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    DemoCell *cell = [tableView dequeueReusableCellWithIdentifier:id_DemoCell];
    if (!cell) {
        cell = [[DemoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id_DemoCell];
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    DemoModel *model = self.dataArray[indexPath.row];
    cell.model = model;
    return cell;
}

#pragma mark - lazy
-(UITableView *)tableView{
    if(!_tableView){
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.estimatedRowHeight = 250;//預估高度
        _tableView.rowHeight = UITableViewAutomaticDimension;
    }
    return _tableView;
}

 /** 從文件加載數據 */
-(NSArray *)dataArray{
    if(!_dataArray){
        NSString *path = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"json"];
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:path] options:0 error:nil];
        _dataArray = [NSArray yy_modelArrayWithClass:[DemoModel class] json:json[@"data"]];
    }
    return _dataArray;
}

@end

複製代碼
2.UITableViewCell AutoLayout部分
  • 新建一個cell命名DemoCell,添加子控件如圖 框架

    DemoCell@2x.png

  • 並脫線生成以下變量工具

@property (weak, nonatomic) IBOutlet UIImageView *iconView;//圖像
@property (weak, nonatomic) IBOutlet UILabel *nameLab;//名字
@property (weak, nonatomic) IBOutlet UILabel *timeLab;//時間
@property (weak, nonatomic) IBOutlet UILabel *titleLab;//標題
@property (weak, nonatomic) IBOutlet UILabel *contentLab;//內容
@property (weak, nonatomic) IBOutlet UILabel *commentLab;//評論數
@property (weak, nonatomic) IBOutlet UILabel *praiseLab;//點贊數

複製代碼
  • 並添加以下約束
圖像-iconView約束:上15,左15,高30,寬高比1:1 
名字-nameLab約束:上下均對其iconView,左5, 並設置橫向抗壓縮優先級爲749即Content Compression Resistance Priority - Horizontal:749
時間-timeLab約束:上下均對齊iconView,左5, 並設置橫向抗拉伸優先級爲250即Content Hugging Priority - Horizontal:250
關注按鈕約束:上下均對齊iconView,右15,寬度50,左5
標題-timeLab約束:左15,上15,右15,
內容-contentLab約束:左15,上15,右15,並設置並設置縱向抗拉伸優先級爲250即Content Hugging Priority - Vertical:250
三張圖約束:上15,左15,右15,中間間隙5,高度65,並設置三張圖等寬,
評論數-commentLab約束:上15,左15,下15,
點贊數-praiseLab約束:上下對齊commentLab,左5,右邊15,並設置橫向抗拉伸優先級爲250即Content Hugging Priority - Horizontal:250
複製代碼
3.UITableViewCell控件賦值部分
-(void)setModel:(DemoModel *)model{
    _model = model;
    
    [_iconView sd_setImageWithURL:[NSURL URLWithString:model.icon]];
    _nameLab.text = model.name;
    _timeLab.text = model.update_time;
    _contentLab.text = model.brief;
    _titleLab.text = model.title;
    _commentLab.text = [NSString stringWithFormat:@"%ld評論",model.comment];
    _praiseLab.text = [NSString stringWithFormat:@"%ld贊",model.praise];
    
    for (int i = 0; i<3; i++) {
        UIImageView *imgView = [self viewWithTag:10+i];
        imgView.image = nil;
    }
    for (int i = 0; i<model.images.count; i++) {
        UIImageView *imgView = [self viewWithTag:10+i];
        [imgView sd_setImageWithURL:[NSURL URLWithString:model.images[i]]];
    }
}
複製代碼
  • 到此,咱們已經完成上圖demo效果,是否是很簡單,沒有寫任何高度計算的代碼.

五.關於組頭、組尾

  • UITableView 的組頭和組尾,也能夠實現自動高度,設置方法以下:
_tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
_tableView.estimatedSectionHeaderHeight = 100;//組頭預估高度
        
_tableView.sectionFooterHeight = UITableViewAutomaticDimension;
 _tableView.estimatedSectionFooterHeight = 100;//組尾預估高度

複製代碼
  • 而且不實現下面兩個組頭,組尾高度代理方法
/** -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ //不實現 } */

/** -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ //不實現 } */
複製代碼

六.關於動態高度,和固定高度混用

  • 此場景一般出如今,一個TableView有多種樣式的cell狀況下,
  • 例如:組0的cell是固定高度,其餘組的cell是動態高度,要怎麼設置呢?
  • 方法以下:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    if(indexPath.section==0){
        return 100;//固定高度
    }else{
        return UITableViewAutomaticDimension;//動態高度
    }
}
複製代碼

七.小結

  • 1.UITableViewCell動態高度,代碼設置部分很簡單不難,主要是AutoLayout部分,要想使用起來,駕輕就熟,開發者除了要掌握普通AutoLayout約束外,還必須熟練掌握Content Hugging Priority(抗拉伸優先級)和Content Compression Resistance Priority(抗壓縮優先級)的用法.
  • 2.熟練使用UITableView cell、組頭、組尾自動高度,能給我開發節省大量的時間.
  • 3.如對Content Hugging Priority(抗拉伸優先級)和Content Compression Resistance Priority(抗壓縮優先級)的用法不熟練的同窗,能夠看我前面文章:AutoLayout進階(二)、 AutoLayout進階(三)、AutoLayout進階(四),有詳細介紹兩個優先級的用法.

代碼地址:github.com/CoderZhuXH/…開發工具

相關文章
相關標籤/搜索