The number of new features introduced with iOS 8 is enormous. On of them is Adaptive Layout
that makes implementing user interfaces much easier. One implementation can handle multiple devices, screen rations and orientations thanks to Size Classes
. That’s a nice feature, but there is more about new UI that makes it great from developer point of view.
All of the iOS applications that I’ve been working on, implements table views to display some data. Sometimes it’s just a simple user interface, but in many cases, the UITableView
is used to present sophisticated UI with text, images etc. With iOS 8, Apple introduces Self-Sizing Table Cells. That means, you don’t have to implement
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
method anymore to have customized cell heights. Now it’s handled automatically by Auto Layout
constraints! You can encapsulated the sizing logic in cells, which makes them more reusable and helps implementing clear UI logic.
As an example, if you have a table view cell with a text view inside, you can add NSLayoutConstraint
inside UITableViewCell
initialization method and you are good to go. No more coding is required to make customized, dynamic cells height. The cell’s height will adjust automatically to contained UITextView
height:
@interface MyTableViewCell () @property (weak, nonatomic) IBOutlet UITextView *textView; @end @implementation MyTableViewCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-textView-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(self.textView)]]; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-textView-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(self.textView)]]; } return self; }
So far that’s one of the best changes that I will surely use in my projects. As I haven’t seen all the goods that are coming, I believe that there are more improvements like this one. Great job Apple!
Update:
It looks like there is one more step required in order to make this feature working. It’s nothing complicated, but you have to configure your UITableView
:
tableView.estimatedRowHeight = 44.0 tableView.rowHeight = UITableViewAutomaticDimension
or it won’t work like expected. Changing value of estimatedRowHeight
doesn’t have huge impact on the layout, but it’s mandatory – otherwise it’s just not working.
Self-sizing cells can be implemented programmatically, like explained above, as well as using Interface Builder. It works in Objective C and Swift. It’s really all about proper constraints added to cell’s contentView
subviews.
Sanal San says:
awesome man..<3
Sanal San says:
how we can implement the same in iOS7 ?
Darrarski says:
I am afraid it’s not that easy in iOS 7. You can try some workaround that allows setting custom cell heights using Interface Builder only, but to take advantage from Auto Layout you will have to use iOS 8 SDK. For iOS 7 check out this: http://stackoverflow.com/questions/8615862/custom-cell-row-height-setting-in-storyboard-is-not-responding/16881312#16881312
Adam Waite (@AdamWaite) says:
It is actually possible on iOS7 but requires some workaround code: http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights
Josh says:
How about for Swift?
Darrarski says:
You can use this technique the same way in Swift. No difference there, apart of syntax of course.
Giorgio says:
Can we add the constraints via storyboard?
Darrarski says:
I suppose we can, although I didn’t test it. I am not sure if it’s not possible to pin cell’s content view to its super view (cell’s view) under IB.
Darrarski says:
I have updated the post with one more step required to setup self-sizing cells. It seams that I missed it when writing the post. After playing a little bit with this feature, I can confirm that it works in ObjC and Swift and can be setup programmatically as well as using Interface Builder.