Reputation: 4820
- (UITableViewCell *)cellForInfoWithCellIdentifier:(NSString *)cellIdentifier
forIndexPath:(NSIndexPath *)indexPath
inTableView:(UITableView *) tableView
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSLog(@"%d", cell.contentView.subviews.count);
if (cell.contentView.subviews.count > 0)
{
[cell.contentView.subviews[0] removeFromSuperview];
}
[cell.contentView addSubview:self.viewsForOptions[self.selectedIndex]];
NSLog(@"%d", cell.contentView.subviews.count);
return cell;
}
The above code is called for a certain section and row in cellForRowAtIndexPath
. This cell is changed whenever a value of the segmented control object is changed.
The method is below:
- (void)testOptionsValueChanged:(id)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
I only have two cells; 1 in each section so the cell == nil
condition is always false
.
Issue:
When the tableView loads the console logs:
0
1
When I change the value of the segmented control, I still get:
0
1
After some more tries, I basically have height of the second view (for the second index) increasing. I can't seem to get a clue why this is really happening.
EDIT:
Other pieces of code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
// test detail view is a constant height
if (indexPath.row == 0)
return 180.0;
}
else if (indexPath.section == 1)
{
// based on the view loaded from the viewForOptions array
if (indexPath.row == 0)
{
return ((UIView *)self.viewsForOptions[self.selectedIndex]).frame.size.height;
}
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DetailCellIdentifier = @"DetailCell";
static NSString *InfoCellIdentifier = @"InfoCell";
UITableViewCell *cell;
if (indexPath.section == 0)
{
// displays views and test button
if (indexPath.row == 0)
{
cell = [self cellForTestDetailWithCellIdentifier:DetailCellIdentifier forIndexPath:indexPath inTableView:tableView];
}
}
else if (indexPath.section == 1)
{
// display the view for information based on segmented control
if (indexPath.row == 0)
{
cell = [self cellForInfoWithCellIdentifier:InfoCellIdentifier forIndexPath:indexPath inTableView:tableView];
}
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)viewDidLoad
{
// set the selected index for the options segmented control
self.selectedIndex = 0;
// instantiate all the views for test segmented control options
self.aViewController = [[AViewController alloc] ...];
self.bViewController = [[BViewController alloc] ...];
self.cViewController = [[CViewController alloc] ...];
// add all the views to an array that will be used by the tableview
self.viewsForOptions = @[self.aViewController, self.bViewController, self.cViewController];
}
Upvotes: 1
Views: 2060
Reputation: 119041
Your 0,1
to 1,1
is caused by the table view reuse mechanism. Basically, the table will not reuse any cell which is already in use. So when you first populate and first refresh the table, new cells will be created. After that, there are enough cells in the reuse queue that aren't being used that no new ones should need to be created (scrolling May create a couple more).
Your height issue could be caused by auto resizing / layout. When you add the subview you should specify what size it should be and how that size should be changed as the superview (the cell) size is changed. And the cell size is changed (log it when you add the subview).
The height of the cell is one part. Usually you would want to set:
UIView *subview = self.viewsForOptions[self.selectedIndex];
subview.frame = cell.contentView.bounds;
[cell.contentView addSubview:subview];
So that when the cell is resized the subview will have the correct size. But this depends on your auto resizing rules. If you set a layout constraint to pin the height and width then you wouldn't need to set the frame.
In either case, you need to specify what happens to the subview frame when the superview frame changes.
Your issue, I guess, is that the cell is resized before being reused and your subview is still attached. So, it gets resized too. Then, in heightForRowAtIndexPath:
you use the height of the subview (now invalid, try logging it) to set the height of the row.
I'd look at changing the implementation of heightForRowAtIndexPath:
to use a configuration based on the selected segment rather than the subview frame height.
Upvotes: 3