tldr; Auto constrains appear to break on push segue and return to view for custom cells
Edit: I have provided a github example proj
The problem of this behavior is when you push a segue the tableView
will call the estimatedHeightForRowAtIndexPath
for the visible cells and reset the cell height to a default value. This happens after the viewWillDisappear
call. If you come back to TableView all the visible cells are messed up..
I solved this problem with a estimatedCellHeightCache
. I simply add this code snipped to the cellForRowAtIndexPath
method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
// put estimated cell height in cache if needed
if (![self isEstimatedRowHeightInCache:indexPath]) {
CGSize cellSize = [cell systemLayoutSizeFittingSize:CGSizeMake(self.view.frame.size.width, 0) withHorizontalFittingPriority:1000.0 verticalFittingPriority:50.0];
[self putEstimatedCellHeightToCache:indexPath height:cellSize.height];
}
...
}
Now you have to implement the estimatedHeightForRowAtIndexPath
as following:
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self getEstimatedCellHeightFromCache:indexPath defaultHeight:41.5];
}
Configure the Cache
Add this property to your .h file:
@property NSMutableDictionary *estimatedRowHeightCache;
Implement methods to put/get/reset.. the cache:
#pragma mark - estimated height cache methods
// put height to cache
- (void) putEstimatedCellHeightToCache:(NSIndexPath *) indexPath height:(CGFloat) height {
[self initEstimatedRowHeightCacheIfNeeded];
[self.estimatedRowHeightCache setValue:[[NSNumber alloc] initWithFloat:height] forKey:[NSString stringWithFormat:@"%d", indexPath.row]];
}
// get height from cache
- (CGFloat) getEstimatedCellHeightFromCache:(NSIndexPath *) indexPath defaultHeight:(CGFloat) defaultHeight {
[self initEstimatedRowHeightCacheIfNeeded];
NSNumber *estimatedHeight = [self.estimatedRowHeightCache valueForKey:[NSString stringWithFormat:@"%d", indexPath.row]];
if (estimatedHeight != nil) {
//NSLog(@"cached: %f", [estimatedHeight floatValue]);
return [estimatedHeight floatValue];
}
//NSLog(@"not cached: %f", defaultHeight);
return defaultHeight;
}
// check if height is on cache
- (BOOL) isEstimatedRowHeightInCache:(NSIndexPath *) indexPath {
if ([self getEstimatedCellHeightFromCache:indexPath defaultHeight:0] > 0) {
return YES;
}
return NO;
}
// init cache
-(void) initEstimatedRowHeightCacheIfNeeded {
if (self.estimatedRowHeightCache == nil) {
self.estimatedRowHeightCache = [[NSMutableDictionary alloc] init];
}
}
// custom [self.tableView reloadData]
-(void) tableViewReloadData {
// clear cache on reload
self.estimatedRowHeightCache = [[NSMutableDictionary alloc] init];
[self.tableView reloadData];
}