preface

The previous chapters detail Aspect Ratio, Content Stretch Priority and Content Compression Resistance Priority. This article will integrate these features to realize the automatic height of UITableViewCell without calculating the height of UITableViewCell and without using the third-party automatic height calculation framework.

UITableViewCell automatic height:

WWDC in iOS8 introduced the concept of self-sizing cell, It is designed to let the cell be responsible for its own height calculation. Since the APP needs to be compatible with iOS7 before, many developers still use manual height calculation or third-party automatic height calculation framework to calculate the height of dynamic UITableViewCell. But with Xcode9 now available, development tools are limited to iOS8 compatibility at a minimum, so we can take advantage of this feature without having to deal with dynamic uitableview cells in the traditional way.

2. Automatic height Demo effect (this effect imitates a certain interface of Wukong Question Answer)

Realization part

1.UITableView only needs the following Settings
  • As follows:
// The estimated cell height is set to a value close to the cell height
self.tableView.estimatedRowHeight = 100;// Can also be omitted without setting,

/ / set the rowHeight to UITableViewAutomaticDimension,
self.tableView.rowHeight = UITableViewAutomaticDimension;// Can be omitted without setting
Copy the code
  • Does not implement the UITableView return cell height proxy method
/** -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{// not implemented} */
Copy the code
2. AutoLayout part
  • In the cell AutoLayout section, add each control constraint and set the Content Hugging Priority and Content Compression Resistance Priority of the dynamic height control

Four. Practical application

Let’s look at the following, in the premise of not calculating the height, how to achieve the above Wukong question answering interface effect

1. Code

The code part is very simple, just a simple UITableView, a custom cell, as follows:

#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;// Estimated height
        _tableView.rowHeight = UITableViewAutomaticDimension;
    }
    return _tableView;
}

 /** Load data from a file */- (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

Copy the code
2. The UITableViewCell AutoLayout parts
  • Create a new cell, name it DemoCell, and add child controls

  • The following variables are generated off-line


@property (weak.nonatomic) IBOutlet UIImageView *iconView;/ / image
@property (weak.nonatomic) IBOutlet UILabel *nameLab;/ / name
@property (weak.nonatomic) IBOutlet UILabel *timeLab;/ / time
@property (weak.nonatomic) IBOutlet UILabel *titleLab;/ / title
@property (weak.nonatomic) IBOutlet UILabel *contentLab;/ / content
@property (weak.nonatomic) IBOutlet UILabel *commentLab;/ / comments
@property (weak.nonatomic) IBOutlet UILabel *praiseLab;/ / thumb up

Copy the code
  • Add the following constraints
Image-iconview constraint: on15And then make a left15High,30The width to height ratio.1:1Name-namelab constraint: both above and below on its iconView, left5And set the horizontal anti-compression priority to749Content Compression Resistance priority-horizontal:749Time-timelab constraint: Align iconView above and below, left5And set the transverse tensile priority as250That is, Content Hugging priority-horizontal:250Focus on button constraints: align iconView above and below, right15Width,50And then make a left5Heading -timeLab constraint: left15On the,15Right,15, contentLab constraint: left15On the,15Right,15And set the longitudinal tensile priority as250That is, Content Hugging priority-vertical:250Three graph constraints: up15And then make a left15Right,15, intermediate gap5, highly65, and set three graphs equal width, number of comments-commentlab constraint: on15And then make a left15Under the,15, Likes -praiselab constraint: Align commentLab above and below, left5On the right15And set the transverse tensile priority as250That is, Content Hugging priority-horizontal:250
Copy the code
3.UITableViewCell control assignment part
- (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 comments "",model.comment];
    _praiseLab.text = [NSString stringWithFormat:@ % ld praise "",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:[NSURLURLWithString:model.images[i]]]; }}Copy the code
  • At this point, we have completed the demo effect above, is not very simple, did not write any height calculation code.

Five. About group head, group tail

  • UITableView group header and group tail can also be set to automatic height as follows:

 _tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
_tableView.estimatedSectionHeaderHeight = 100;// Group head estimated height
        
_tableView.sectionFooterHeight = UITableViewAutomaticDimension;
 _tableView.estimatedSectionFooterHeight = 100;// Group tail estimated height

Copy the code
  • And do not implement the following two group header, group tail height proxy methods
/ * * - (CGFloat) tableView: (UITableView *) tableView heightForFooterInSection: (NSInteger) section {/ / not achieve} * /

/ * * - (CGFloat) tableView: (UITableView *) tableView heightForHeaderInSection: (NSInteger) section {/ / not achieve} * /
Copy the code

6. For dynamic altitude, and fixed altitude mixed

  • This scenario is usually when a TableView has multiple types of cells,
  • For example, the cell of group 0 is a fixed height, and the cell of other groups is a dynamic height. How do I set this parameter?
  • The method is as follows:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    if(indexPath.section==0) {return 100;// Fix the height
    }else{
        return UITableViewAutomaticDimension;// Dynamic height}}Copy the code

Nodule seven.

  • 1. The UITableViewCell’s dynamic height, which seems to be both easy to set up and easy to use, mainly the AutoLayout part, will require developers to master Content Hugging as well as ordinary AutoLayout constraints Use of Priority and Content Compression Resistance Priority.
  • 2. Skilled use of UITableView Cell, group header, group tail automatic height, can save a lot of time for my development.
  • 3. For those who are not familiar with the usages of Content Hugging Priority and Content Compression Resistance Priority, watch my previous article :AutoLayout Progression (2) AutoLayout progression (3), AutoLayout progression (4), there is a detailed introduction to the use of the two priorities.

Code address :github.com/CoderZhuXH/…