The first method is to set the contentView property of the UITableViewCell in the controller that acts as the UITableViewDataSource - specifically in this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MY_CELL_ID"]; if (!cell) { cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MY_CELL_ID"]; [[cell contentView] addSubview:[self customCellContentForCell:cell]]; } return cell; }
With a breakpoint set at the highlighted line above, here is the call stack:
Notice that the frames of each cell are exactly the same.
The second method to customize a UITableViewCell involves overriding the layoutSubviews method. Here's what the call stack looks like when the layoutSubviews override is called:
I captured the entire stack from the main all the way up to my breakpoint to show the UITableViewCell's layoutSubviews method is called on an altogether different run loop than when the UITableViewDataSource's tableView:cellForRowAtIndexPath: method is called. It actually turns out that the data source method is called first, for as many times as there are rows. Then the UITableView's layoutSubviews override methods are called on another run loop.
So here is the debugger after the fourth UITableViewCell's layoutSubviews method is called:
This time we see that the frame's orign's y-coordinate increases by the height of the table row.
Recall that a UIView's frame property is defined by its position in its superview. So, given all of the above information, this means that a developer has to be aware that by the time layoutSubview is called, the UIView is already in its superview.
On the other hand, when the cell is created in the UITableViewDataSource protocol method, it has not yet been assigned to a superview.
Define your frames appropriately.
No comments:
Post a Comment