5
votes

I know how to animate the height change of a UITableViewCell using the method seen here: Can you animate a height change on a UITableViewCell when selected?

However, using that method, the UITableView will scroll at the same time, which I don't want it to do.

I have a UITableView with very few cells; it takes up less than the screen height. The bottom cell has a UITextField and, when it starts editing, I manually set the content offset of the UITableView so that the cell with the UITextField is scrolled to the top. Then, based on the input in the UITextField, I may want to increase the size of the UITableViewCell to show extra options, more or less.

The problem is that, when animating this change, it will reposition the UITableView so that my UITextField is no longer at the top.

This is what I'm doing, more or less:

self.customAmountCellSize = height;

[self.tableView beginUpdates];
[self.tableView endUpdates];

I have also tried

self.customAmountCellSize = height;
CGPoint originalOffset = self.tableView.contentOffset;

[self.tableView beginUpdates];
[self.tableView endUpdates];

[self.tableView setContentOffset:originalOffset animated:NO];

I want the row height animation, I do not want the UITableView to scroll as a result.

Any ideas?

2
I'm scrolling the UITableView to a ContentOffset that is not normally achievable via dragging because the UITableView's content is less than the size of a single screen. However, the bottom cell needs to be scrolled to the top when it is editing. When I change the size of the bottom cell during editing, the UITableView scrolls back to a ContentOffset that would be achievable via dragging (in this case, back to a content offset of (0, 0)).MikeS

2 Answers

3
votes

It appears the problem you're encountering is that your table view is scrolled past the bottom so when you update its content it will attempt to fix that.

There are two approaches you could take to prevent scrolling:

  1. Set the table view's content inset to be the height of the initial white space:

    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, verticalGap, 0);
    
  2. Add an empty footer view with the same height as the vertical gap:

    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, verticalGap)];
    

In both cases, you will need to calculate the vertical space you are trying to achieve. You then need to restore the contentInset or tableFooterView to its original state when you are done.

1
votes

I think the table view is scrolling because your text field is becoming the first responder, and not because of the cell height change. Try keeping the cell height the same and just adjusting the offset to be sure.

If I am correct, than here's the solution: UITableView automatically tries to scroll when your keyboard appears. To fix this, set the content offset to your desired offset in a dispatch to the main queue, which will fire at the beginning of the next runloop. Put the following code inside your response to a UIKeyboardWillShowNotification, or in a UITextFieldDelegate shouldBeginEditing method:

// Get the current offset prior to the keyboard animation
CGPoint currentOffset = self.tableView.contentOffset;
UIEdgeInsets currentInsets = self.tableView.contentInset;
__weak SomeTableViewControllerClass *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animationWithDuration:0 animations:{
        // set the content offset back to what it was
        weakSelf.tableView.contentOffset = currentOffset;
        weakSelf.tableView.contentInset = currentInsets;
    } completion:nil];
});

Similar fixes are sometimes necessary for the contentInset.bottom of a table view, depending on the frame of your UITableView and other factors.