0

I have been following this tutorial to implement dynamic cell height. dynamic-table-view-cell-height But it only works in ios 7 for me and not in ios 8. However it does work in ios 8 on the iPAD so I'm a little stumped why it doesn't work on the iphone. Whilst I have followed the code pretty exactly there are a couple of differences between the tutorial and the way I have implemented it and as I don't know enough about autolayout and tables I'm not sure if this is what is causing my problem.

Firstly on the tutorial the tableView has trailing and leading edges exactly equal to 0 to the superview. In my implementation I have created proportional constraints so that I scale the tableView within multiple different layouts. To explain further:

Here is a picture of my TableView using proportional constraints across multiple different devices. enter image description here

To achieve this I implemented the following constraints: enter image description here

enter image description here

enter image description here

enter image description here

Is it possible that the cell height cannot be calculated by AutoLayout because the tableView has a dynamic height?

The second difference that I can see between my implementation and the tutorial is the data source. I am taking my data from a call to an SLQ3Lite database whereas the tutorial is taking its data from an xml feed. I am confident that the data is populating the cells because when I look at my implementation on an IPAD I can see the data like so: enter image description here

But on an iphone this is what appears: The table is visible but no cells have been written to the table. enter image description here

When I use the debugger I can see that records are being successfully retrieved from the database, but they are not being written to the table.

Here is the code which is very long (Sorry)

 #import "favouritedViewController.h" #import "DBManager.h" #import "favouritedCell.h" @interface favouritedViewController () @property (strong, nonatomic) IBOutlet UITableView *tableView; @property (strong, nonatomic) NSArray *favourites; @property (nonatomic, strong) DBManager *dbManager; typedef void (^CompletionBlock)(); -(void)loadData; -(void)reloadDataWithCompletions:(CompletionBlock)completionBlock; @end @implementation favouritedViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.dbManager = [[DBManager alloc] initWithDatabaseFilename:@"tomhaisdb.sql"]; self.tableView.delegate = self; self.tableView.dataSource = self; [self loadData]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)loadData { NSString *query = @"select * from favourites"; if (self.favourites != nil) { self.favourites = nil; } self.favourites = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]]; /* [self reloadDataWithCompletions:^{ self.tableView.backgroundColor = [UIColor colorWithRed:28.0f/255.0f green:30.0f/255.0f blue:35.0f/255.0f alpha:1]; }];*/ [self reloadTableViewContent]; } /*-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; }*/ -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.favourites.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ return [self basicCellAtIndexPath:indexPath]; } - (void)reloadTableViewContent { dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; [self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; }); } -(favouritedCell *)basicCellAtIndexPath:(NSIndexPath *)indexPath { favouritedCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"favouriteCell" forIndexPath:indexPath]; [self configureBasicCell:cell atIndexPath:indexPath]; return cell; } -(void)configureBasicCell:(favouritedCell *)cell atIndexPath:(NSIndexPath *)indexPath{ NSInteger indexOfTomhaisText = [self.dbManager.arrColumnNames indexOfObject:@"tomhaisText"]; NSString *tomhaisText = [[self.favourites objectAtIndex:indexPath.row] objectAtIndex:indexOfTomhaisText]; [self setTomhaisForCell:cell item:tomhaisText]; [self setAnswerForCell:cell item:tomhaisText]; // change this later } -(void)setTomhaisForCell:(favouritedCell *)cell item:(NSString *)item{ [cell.favouriteText setText:item]; } -(void)setAnswerForCell:(favouritedCell *)cell item:(NSString *)item{ [cell.answer setText:item]; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return [self heightForFavouriteCellAtIndexPath:indexPath]; } -(CGFloat)heightForFavouriteCellAtIndexPath:(NSIndexPath *)indexPath{ static favouritedCell *sizingCell = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"favouriteCell"]; }); [self configureBasicCell:sizingCell atIndexPath:indexPath]; return [self calculateHeightForConfiguredSizingCell:sizingCell]; } -(CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell{ sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(sizingCell.bounds)); [sizingCell setNeedsLayout]; [sizingCell layoutIfNeeded]; CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; return size.height + 1.0f; } -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 155.0f; } 

EDIT 1


enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

Here is a picture of it running on ios 7 (which is working) enter image description here

And this is the Log output

2015-06-01 18:43:40.855 Facts[62233:607] Number of rows: 2 2015-06-01 18:43:43.996 Facts[62233:607] Bounds before Layout {{0, 0}, {256, 82}} 2015-06-01 18:43:55.068 Facts[62233:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 18:44:09.409 Facts[62233:607] Bounds after layout {{0, 0}, {256, 82}} 2015-06-01 18:44:12.843 Facts[62233:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 18:44:21.462 Facts[62233:607] Bounds before Layout {{0, 0}, {256, 82}} 2015-06-01 18:44:23.884 Facts[62233:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 18:44:30.536 Facts[62233:607] Bounds after layout {{0, 0}, {256, 82}} 2015-06-01 18:44:32.278 Facts[62233:607] Content View before Layout {{0, 0}, {256, 82}}

From this piece of code:

 -(CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell{ sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(sizingCell.bounds)); NSLog(@"Bounds before Layout %@", NSStringFromCGRect(sizingCell.bounds)); NSLog(@"Content View before Layout %@", NSStringFromCGRect(sizingCell.contentView.bounds)); [sizingCell setNeedsLayout]; [sizingCell layoutIfNeeded]; CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; NSLog(@"Bounds after layout %@", NSStringFromCGRect(sizingCell.bounds)); NSLog(@"Content View before Layout %@", NSStringFromCGRect(sizingCell.contentView.bounds)); return size.height + 1.0f; } 

But on ios8 this is what I see: enter image description here

and this is the output:

2015-06-01 18:47:14.688 Facts[62306:81355636] Bounds before Layout {{0, 0}, {256, 44}} 2015-06-01 18:47:14.688 Facts[62306:81355636] Content View before Layout {{0, 0}, {256, 44}} 2015-06-01 18:47:14.688 Facts[62306:81355636] Bounds after layout {{0, 0}, {256, 44}} 2015-06-01 18:47:14.688 Facts[62306:81355636] Content View before Layout {{0, 0}, {256, 44}}

The sizingCell in ios7 is reading the correct bounds for the cell's contents but in ios8 it is not.

1
  • Can you please show your constraints for the cell/labels? Commented Jun 1, 2015 at 17:39

2 Answers 2

1

I found https://github.com/forkingdog/UITableView-FDTemplateLayoutCell library useful. I have tried all but not work. Now this library dynamically calculate height of UITableView row.

Sign up to request clarification or add additional context in comments.

Comments

0

You're doing too much; Apple can handle the leading and trailing spacing for you.

0 is exactly the right number to use, but you pin to the superview.margin, not the superview. Apple will adjust the margin for you to their recommended margin, dependent on the device. (Wider on 4.7", narrower on 4".)

FYI, 0 times any multiplier factor is always 0, so your current constraints won't do what you expect they should.

The reason why the cell height is off is due to a misplaced frame (that Interface Builder couldn't warn about because the label constraints were not installed for anyXany).

IOS 7 could still solve the cell height, but iOS 8 requires the cell height to be initially correct (solvable).

3 Comments

I'm not sure I understand your answer. I am not multiplying by 0 I'm multiplying by the second Item which is .center X which would be .5 - so in the instance of leading space .2 * .5 = .1 so the leading space will be 10% of the width of the screen. Similarly the trailing spaces is the multiplier 1.8 is multiplying center.x or .5 = .9 or will be aligned to 90% of the device width. So I don't think it is my trailing or leading space - It also works in ios7 but not in io8
Sorry, too much going on in the question! You're right about the tableView. For the cell, you do want 0 as your leading/trailing space, and let the system handle the margins. The fact that the table height can change won't impact the cell height calculation. They're completely independent.
Yes I appreciate that - It may be the loooongest question ever on Stackoverflow. I appreciate you taking the time to look at it. I've added an edit at the bottom with the label's constraints within the cell. The cell itself doesn't have any constraints but it does have row Height set to 82 and custom ticked in storyboard

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.