The reason for writing this tool

The latest business requirement is to change a very old interface: all content is implemented by frame, no XIB, no Autolayout, and height is returned by manually calculating the sum of the contents of each control, and there are four styles based on the data requested by the network, so it sounds big

After I forced myself to change the interface, I saw the thick if at the height of the computing cell Else really can’t do it, wondering if I can find any third party to do it, then REMEMBERED FDTemplateLayoutCell, baidu produced a very famous calculation autolayout tool, used before, to modify the original code structure a lot, put cellForRowAtIndexPath LayoutSuview (layoutSuview, layoutSuview, layoutSuview, layoutSuview, layoutSuview, layoutSuview, layoutSuview, layoutSuview) So I started writing this tool

In the beginning, I just wanted to get the height as simple as possible and keep the original code as unchanged as possible. Later, I realized that even autolayout can also be used to get the correct cell by layoutIfNeed, so I added Autolayout to the system. Later, I found the way to calculate the frame (need to register one) View (bottom view) can be used in incomplete autolayout, so incomplete constraints are supported


In addition, some people might ask, after iOS11 UITableView is enabled by default estimatedRowHeight, why do I need to manually calculate the height?

The answer, of course, is that it doesn’t work

Updating cells on most iOS11 subversions has animation issues, even when contentOffset is not CGPointZero,tableView If you set estimatedRowHeight to 0, you don’t have to do that. Even if Apple turns this on by default, it’s going to have to turn it off to implement heightForRowAtIndexPath

So it’s a very useful tool


function

  • High performance: Computes cell height as little as possible, and provides memory and disk caching.
  • Automatic update: Updates based on the data model hash that automatically updates the cache when the data source or TableView width changes.
  • Memory management: Automatically clears the memory cache when the system indicates that the memory is insufficient.
  • Low invasions: You don’t need to change any code structure to use this framework, unlike FDTemplateLayoutCell, which has to change a lot of the original code based on their design.
  • Lightweight: The core components of this library are a file, a class, and a TableView category.
  • Easy to use: With just one line of code, you can enjoy highly automated computing.

Open source address: Github

Ask for a star, by the way! thank you

Method of use

#import "UITableView+MDKAutoLayoutHeight.h"

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
	return [tableView.autoLayoutHeight heightForRowAtIndexPath:indexPath];
}

Copy the code

No, that’s it. It’s super simple

If you need to do something with the height, you can use this method to recalculate the row height

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
	return [tableView.autoLayoutHeight heightForRowAtIndexPath:indexPath cacheKey:acachekey handle:^CGFloat(__kindof UITableViewCell *cell, CGFloat height) {
	  return height + 20;
	}];
}

Copy the code

If your cell is not completely filled with the constraints of the contentView, you can use itMDKAutoLayoutRegisterHeightSet which view is the bottom view:

#import "UITableView+MDKAutoLayoutHeight.h"

@interface PartOfAutolayoutCell()
@proterty(nonatomic,strong)UIView *bottomView;
@end

@implementation PartOfAutolayoutCell
+(void)initialize{
	MDKAutoLayoutRegisterHeight(self, bottomView)
}
@end

Copy the code

If this method is implemented, the tools will also work with frame cells, as long as you are laying them out in a layoutSubview (other methods such as sizeThatFit will also work). Please let me know if you come across any places where setting the position of the frame cell control is invalid

By the way, MDKAutoLayoutRegisterHeight () If you are using swift, use MDKAutoLayoutHeight.(registerHeight:_decisionView:#keyPath(view.bottom)) to fill in the attribute name of the view at the bottom

Cache height in memory

If acachekey returns nil or @ “” in the heightForRow method, you need to manually return acachekey as follows

If you need the height of the cell to cache memory, only need to introduce in the cell < MDKTableviewCellCacheHeightDelegate >, implementation – MDKModelHash method, returns a string with uniqueness to me, such as:

-(NSString *)MDKModelHash{
	return @(_model.ID).description;
}

Copy the code

If it is possible to change the contents of the cell, you can send me the ID and the identifier that determines whether the contents of the cell have changed, such as:

-(NSString *)MDKModelHash{
	return [NSString stringWithFormat:@"% @ % @",@(_model.ID),@(_model.isDelete)];
}

Copy the code

Wait, wait, wait…..

The installation

pod 'UITableView-MDKAutoLayoutHeight'

Copy the code

If you need to cache the height to disk

pod 'UITableView-MDKAutoLayoutHeight/diskCache'

Copy the code

So when tableView dealloc writes the cache in memory to disk and I’ve provided the following methods to manage the cache on disk

import UITableView+MDKAutoLayoutHeightDiskCache.h - (void)updateDiskCache; // For some tableView that will always live - (void)removeCacheFor (Class)cell; - (void)removeAllCache;Copy the code

Known issues

If you dequeue the cell like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

	return [tableView dequeueReusableCellWithIdentifier:@"Identifier" forIndexPath:indexPath];	
}

Copy the code

App will crash, because I was obtained by this datasource cell, and – dequeueReusableCellWithIdentifier: forIndexPath: This method calls table. delegate-HeightForRowatIndexpath so it goes into an infinite loop…… Solution is this way, they should not change – dequeueReusableCellWithIdentifier: qeueu cell

I really haven’t thought of any reason why I must use this method. If there is any situation in which I must use this dequeue cell, please tell me the reason. Thank you

Thank you

Some of the code used to determine the width of the contentView comes from the UitableView-fdTemPlatelayOutCell