I am creating an app that I want to run under both iOS7 and iOS8, that has variable table cell heights. In iOS7 I used to define a prototype cell and then use this in heightForRowAtIndexPath to calculate the height, based on the size of the text placed into labels.
This no longer seems to work when using Xcode 6. I created a small test app today to see if I was going crazy (maybe I am). I started by NOT defining heightForRowAtIndexPath at all. When I test it with iOS7 and iOS8 devices it behaves differently. In the iOS8 device it automatically determines the cell height and works fine. In iOS7 the cells are returned all the same height. It doesn't do the automatic height adjustment for the cells with variable text, for iOS7, only for iOS8.
So... me thinking... hmmm... under iOS8 I can use auto layout to determine the height and only implement heightForRowAtIndexPath for iOS7...
Okay, so... I tried adding in heightForRowAtIndexPath. Under iOS7 it crashes on method systemLayoutSizeFittingSize. I played with this for hours and nothing I do seems to change this. It is extremely simple code.
Here is the UITableViewController code:
//
// TestTableViewController.m
// testTables
//
#import "TestTableViewController.h"
#import "Cell1.h"
@interface TestTableViewController ()
@property (nonatomic, strong) Cell1 *cellPrototype;
@end
@implementation TestTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:@"Cell1" bundle:nil] forCellReuseIdentifier:@"Cell1"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
self.cellPrototype = [self.tableView dequeueReusableCellWithIdentifier:@"Cell1"];
self.cellPrototype.label1.text = [self cellContents:indexPath];
[self.cellPrototype layoutIfNeeded];
CGSize size = [self.cellPrototype systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Cell1 *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell1" forIndexPath:indexPath];
cell.label1.text = [self cellContents:indexPath];
return cell;
}
- (NSString*)cellContents:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return @"one line";
}
else if (indexPath.row == 1) {
return @"two lines I think will result from this piece of text that goes over";
}
else if (indexPath.row == 2) {
return @"three lines I think will result from this piece of text that goes over and then even extends a little more again";
}
else {
return @"three lines I think will result from this piece of text that goes over and then even extends a little more again, and then extends over more and more lines like it will go on forever and never end but in fact it does end right here.";
}
}
@end
Here is the cell header (there is nothing in the .m file):
//
// Cell1.h
// testTables
//
#import <UIKit/UIKit.h>
@interface Cell1 : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *label1;
@end
Here is the xib for the cell. As you can see, it's not complex:
So... does this old method not work any more? How can I get variable height cells that will run in both iOSes?