Question

I have a rather complex form being laid out in a UITableView. This form has some UICollectionView inside a table view cell and also some pickers that show up the same way it does on Calendar app:

Image

Now when I do this on my app, one of the UICollectionView I have gets taller than how it started - and it keeps going (I added a red border to make sure it was the UICollectionView that was being resized):

Image

I tried debugging the UICollectionView view property but it never changes (and it's getter/setter aren't called more than what I expected) - even though when I print it on cellForRowAtIndexPath it does shows up resized. Is there any way I can debug this better, or have someone been at the same situation?

Thanks!

Code:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//self.campos is a dictionary with sections and rows stored
    NSMutableArray *infoCampos = [[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"];
NSDictionary *infoCampo = [infoCampos objectAtIndex:indexPath.row];

if ([[infoCampo objectForKey:@"nome"] isEqualToString:@"dosePorComprimido"]) {
    //Remove picker cell if finds it
    for (infoCampo in infoCampos) {
        if ([infoCampo objectForKey:@"view"] == self.dosagemMedicamento.view) {
            [infoCampos removeObject:infoCampo];
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
            return;
        }
    }

    //Insert new cell
    infoCampo = [infoCampos objectAtIndex:indexPath.row];
    [infoCampos addObject:@{@"tipo":@5, @"view":self.dosagemMedicamento.view, @"nome":[infoCampo objectForKey:@"nome"]}];
    [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.dosagemMedicamento.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[pickerDosagem]|" options:0 metrics:nil views:@{@"pickerDosagem":self.dosagemMedicamento.view}]];
}
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        view = (UIView *) [infoCampo objectForKey:@"view"];
        return view.frame.size.height;
    }

    return 44.0f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:

(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    NSMutableDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

cell = [tableView dequeueReusableCellWithIdentifier:[[infoCampo objectForKey:@"nome"] stringByAppendingString:@"ViewLinhaCellView"] forIndexPath:indexPath];

        view = [cell viewWithTag:1];

        [view addSubview:[infoCampo objectForKey:@"view"]];

return cell;
}

EDIT: forgot to mention that I'm not updating the table view with reloadData but only the needed sections/rows with reloadRowsAtIndexPaths and reloadSections. So that makes it even weirder because I'm not reloading that particular section.

EDIT 2: added data source e delegate code

Was it helpful?

Solution

I believe your problem is here, in the implementation of tableView:heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        view = (UIView *) [infoCampo objectForKey:@"view"];
        return view.frame.size.height;
    }

    return 44.0f;
}

The view is probably getting resized by auto layout or its autoresizing mask. There isn't enough info here to say exactly why, but table views and auto layout can have some funny behavior. I recommend just returning a height that you set, rather than getting the height from the view:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        if ([infoCampo objectForKey:@"viewHeight"]) {
            return [[infoCampo objectForKey:@"viewHeight"] floatValue];
        } else {
            return 216.0f;
        }
    }

    return 44.0f;
}

The viewHeight key allows you to specify a custom height for each cell's view, but this implementation also returns a default height (216) that happens to be the standard height for picker views.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top