Skip to content

Commit 7d4d16e

Browse files
committed
Update sample project for iOS 8 self sizing cells
1 parent 80b2c87 commit 7d4d16e

3 files changed

Lines changed: 15 additions & 105 deletions

File tree

TableViewCellWithAutoLayout.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@
405405
GCC_PRECOMPILE_PREFIX_HEADER = YES;
406406
GCC_PREFIX_HEADER = "TableViewCellWithAutoLayout/TableViewCellWithAutoLayout-Prefix.pch";
407407
INFOPLIST_FILE = "TableViewCellWithAutoLayout/TableViewCellWithAutoLayout-Info.plist";
408+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
408409
PRODUCT_NAME = "$(TARGET_NAME)";
409410
WRAPPER_EXTENSION = app;
410411
};
@@ -418,6 +419,7 @@
418419
GCC_PRECOMPILE_PREFIX_HEADER = YES;
419420
GCC_PREFIX_HEADER = "TableViewCellWithAutoLayout/TableViewCellWithAutoLayout-Prefix.pch";
420421
INFOPLIST_FILE = "TableViewCellWithAutoLayout/TableViewCellWithAutoLayout-Info.plist";
422+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
421423
PRODUCT_NAME = "$(TARGET_NAME)";
422424
WRAPPER_EXTENSION = app;
423425
};

TableViewCellWithAutoLayout/TableViewController/RJTableViewCell.m

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus
4646
[self.titleLabel setNumberOfLines:1];
4747
[self.titleLabel setTextAlignment:NSTextAlignmentLeft];
4848
[self.titleLabel setTextColor:[UIColor blackColor]];
49-
self.titleLabel.backgroundColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.1];
49+
self.titleLabel.backgroundColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.1]; // light blue
5050

5151
self.bodyLabel = [UILabel newAutoLayoutView];
5252
[self.bodyLabel setLineBreakMode:NSLineBreakByTruncatingTail];
5353
[self.bodyLabel setNumberOfLines:0];
5454
[self.bodyLabel setTextAlignment:NSTextAlignmentLeft];
5555
[self.bodyLabel setTextColor:[UIColor darkGrayColor]];
56-
self.bodyLabel.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.1];
56+
self.bodyLabel.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.1]; // light red
5757

58-
self.contentView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.1];
58+
self.contentView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.1]; // light green
5959

6060
[self.contentView addSubview:self.titleLabel];
6161
[self.contentView addSubview:self.bodyLabel];
@@ -86,12 +86,7 @@ - (void)updateConstraints
8686
[self.titleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:kLabelHorizontalInsets];
8787
[self.titleLabel autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:kLabelHorizontalInsets];
8888

89-
// This is the constraint that connects the title and body labels. It is a "greater than or equal" inequality so that if the row height is
90-
// slightly larger than what is actually required to fit the cell's subviews, the extra space will go here. (This is the case on iOS 7
91-
// where the cell separator is only 0.5 points tall, but in the tableView:heightForRowAtIndexPath: method of the view controller, we add
92-
// a full 1.0 point in extra height to account for it, which results in 0.5 points extra space in the cell.)
93-
// See https://github.com/smileyborg/TableViewCellWithAutoLayout/issues/3 for more info.
94-
[self.bodyLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.titleLabel withOffset:kLabelVerticalInsets relation:NSLayoutRelationGreaterThanOrEqual];
89+
[self.bodyLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.titleLabel withOffset:kLabelVerticalInsets];
9590

9691
[UIView autoSetPriority:UILayoutPriorityRequired forConstraints:^{
9792
[self.bodyLabel autoSetContentCompressionResistancePriorityForAxis:ALAxisVertical];
@@ -103,20 +98,6 @@ - (void)updateConstraints
10398
self.didSetupConstraints = YES;
10499
}
105100

106-
- (void)layoutSubviews
107-
{
108-
[super layoutSubviews];
109-
110-
// Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
111-
// need to use to set the preferredMaxLayoutWidth below.
112-
[self.contentView setNeedsLayout];
113-
[self.contentView layoutIfNeeded];
114-
115-
// Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
116-
// as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
117-
self.bodyLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.bodyLabel.frame);
118-
}
119-
120101
- (void)updateFonts
121102
{
122103
self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];

TableViewCellWithAutoLayout/TableViewController/RJTableViewController.m

Lines changed: 9 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,6 @@ @interface RJTableViewController ()
3434

3535
@property (strong, nonatomic) RJModel *model;
3636

37-
// A dictionary of offscreen cells that are used within the tableView:heightForRowAtIndexPath: method to
38-
// handle the height calculations. These are never drawn onscreen. The dictionary is in the format:
39-
// { NSString *reuseIdentifier : UITableViewCell *offscreenCell, ... }
40-
@property (strong, nonatomic) NSMutableDictionary *offscreenCells;
41-
42-
// For iOS 7.0.x compatibility ONLY (this bug is fixed in iOS 7.1):
43-
// This property is used to work around the constraint exception that is thrown if the
44-
// estimated row height for an inserted row is greater than the actual height for that row.
45-
// See: https://github.com/caoimghgin/TableViewCellWithAutoLayout/issues/6
46-
@property (assign, nonatomic) BOOL isInsertingRow;
47-
4837
@end
4938

5039
@implementation RJTableViewController
@@ -55,7 +44,6 @@ - (id)initWithStyle:(UITableViewStyle)style
5544
if (self) {
5645
self.model = [[RJModel alloc] init];
5746
[self.model populateDataSource];
58-
self.offscreenCells = [NSMutableDictionary dictionary];
5947
}
6048
return self;
6149
}
@@ -64,17 +52,21 @@ - (void)viewDidLoad
6452
{
6553
[super viewDidLoad];
6654

67-
self.title = @"Auto Layout Table View";
55+
self.title = @"iOS 8 Self Sizing Cells";
6856
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(clear:)];
6957
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addRow:)];
7058

59+
self.tableView.allowsSelection = NO;
60+
7161
[self.tableView registerClass:[RJTableViewCell class] forCellReuseIdentifier:CellIdentifier];
7262

63+
// Self-sizing table view cells in iOS 8 require that the rowHeight property of the table view be set to the constant UITableViewAutomaticDimension
64+
self.tableView.rowHeight = UITableViewAutomaticDimension;
65+
66+
// Self-sizing table view cells in iOS 8 are enabled when the estimatedRowHeight property of the table view is set to a non-zero value.
7367
// Setting the estimated row height prevents the table view from calling tableView:heightForRowAtIndexPath: for every row in the table on first load;
7468
// it will only be called as cells are about to scroll onscreen. This is a major performance optimization.
75-
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
76-
77-
self.tableView.allowsSelection = NO;
69+
self.tableView.estimatedRowHeight = 44.0;
7870
}
7971

8072
- (void)viewDidAppear:(BOOL)animated
@@ -120,12 +112,8 @@ - (void)addRow:(id)sender
120112
{
121113
[self.model addSingleItemToDataSource];
122114

123-
self.isInsertingRow = YES;
124-
125115
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:[self.model.dataSource count] - 1 inSection:0];
126116
[self.tableView insertRowsAtIndexPaths:@[lastIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
127-
128-
self.isInsertingRow = NO;
129117
}
130118

131119
#pragma mark - Table view data source
@@ -157,58 +145,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
157145
return cell;
158146
}
159147

160-
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
161-
{
162-
// This project has only one cell identifier, but if you are have more than one, this is the time
163-
// to figure out which reuse identifier should be used for the cell at this index path.
164-
NSString *reuseIdentifier = CellIdentifier;
165-
166-
// Use the dictionary of offscreen cells to get a cell for the reuse identifier, creating a cell and storing
167-
// it in the dictionary if one hasn't already been added for the reuse identifier.
168-
// WARNING: Don't call the table view's dequeueReusableCellWithIdentifier: method here because this will result
169-
// in a memory leak as the cell is created but never returned from the tableView:cellForRowAtIndexPath: method!
170-
RJTableViewCell *cell = [self.offscreenCells objectForKey:reuseIdentifier];
171-
if (!cell) {
172-
cell = [[RJTableViewCell alloc] init];
173-
[self.offscreenCells setObject:cell forKey:reuseIdentifier];
174-
}
175-
176-
// Configure the cell for this indexPath
177-
[cell updateFonts];
178-
NSDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:indexPath.row];
179-
cell.titleLabel.text = [dataSourceItem valueForKey:@"title"];
180-
cell.bodyLabel.text = [dataSourceItem valueForKey:@"body"];
181-
182-
// Make sure the constraints have been added to this cell, since it may have just been created from scratch
183-
[cell setNeedsUpdateConstraints];
184-
[cell updateConstraintsIfNeeded];
185-
186-
// The cell's width must be set to the same size it will end up at once it is in the table view.
187-
// This is important so that we'll get the correct height for different table view widths, since our cell's
188-
// height depends on its width due to the multi-line UILabel word wrapping. Don't need to do this above in
189-
// -[tableView:cellForRowAtIndexPath:] because it happens automatically when the cell is used in the table view.
190-
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
191-
// NOTE: if you are displaying a section index (e.g. alphabet along the right side of the table view), or
192-
// if you are using a grouped table view style where cells have insets to the edges of the table view,
193-
// you'll need to adjust the cell.bounds.size.width to be smaller than the full width of the table view we just
194-
// set it to above. See http://stackoverflow.com/questions/3647242 for discussion on the section index width.
195-
196-
// Do the layout pass on the cell, which will calculate the frames for all the views based on the constraints
197-
// (Note that the preferredMaxLayoutWidth is set on multi-line UILabels inside the -[layoutSubviews] method
198-
// in the UITableViewCell subclass
199-
[cell setNeedsLayout];
200-
[cell layoutIfNeeded];
201-
202-
// Get the actual height required for the cell
203-
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
204-
205-
// Add an extra point to the height to account for the cell separator, which is added between the bottom
206-
// of the cell's contentView and the bottom of the table view cell.
207-
height += 1;
208-
209-
return height;
210-
}
211-
212148
/*
213149
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
214150
{
@@ -219,17 +155,8 @@ - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(
219155
// Only implement this method if you have row heights that vary by extreme amounts and you notice the scroll indicator
220156
// "jumping" as you scroll the table view when using a constant estimatedRowHeight. If you do implement this method,
221157
// be sure to do as little work as possible to get a reasonably-accurate estimate.
222-
223-
// NOTE for iOS 7.0.x ONLY, this bug has been fixed by Apple as of iOS 7.1:
224-
// A constraint exception will be thrown if the estimated row height for an inserted row is greater
225-
// than the actual height for that row. In order to work around this, we need to return the actual
226-
// height for the the row when inserting into the table view - uncomment the below 3 lines of code.
227-
// See: https://github.com/caoimghgin/TableViewCellWithAutoLayout/issues/6
228-
// if (self.isInsertingRow) {
229-
// return [self tableView:tableView heightForRowAtIndexPath:indexPath];
230-
// }
231158
232-
return UITableViewAutomaticDimension;
159+
return 44.0;
233160
}
234161
*/
235162

0 commit comments

Comments
 (0)