Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView bouncing back to the top of a section when calling reloadRowsAtIndexPaths

When a user taps a button in one of my rows I am updating the underlying model for that row and then calling reloadRowsAtIndexPaths for the given row (i.e. single row reload).

- (IBAction)handleCompleteTouchEvent:(UIButton *)sender {
    NSIndexPath *indexPath = [self.tableView indexPathForView:sender];
    id item = [self dataForIndexPath:indexPath];

    if ([item respondsToSelector:@selector(completed)]) {
        // toogle completed value
        BOOL completed = ![[item valueForKey:@"completed"] boolValue];
        [item setValue:[NSNumber numberWithBool:completed] forKey:@"completed"];

        [self.tableView beginUpdates];
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];
    }
}

The problem is that the table view bounces back to the top of the section after making this call. How can I prevent this from occurring and keep the scroll position where it is?

like image 885
xsee Avatar asked Jul 15 '14 20:07

xsee


People also ask

How do I scroll to top Tableview?

To scroll to the top of our tableview we need to create a new IndexPath . This index path has two arguments, row and section . All we want to do is scroll to the top of the table view, therefore we pass 0 for the row argument and 0 for the section argument. UITableView has the scrollToRow method built in.

What is UITableView in Swift?

A view that presents data using rows in a single column. iOS 2.0+ iPadOS 2.0+ Mac Catalyst 13.1+ tvOS 9.0+

What is IndexPath in Tableview Swift?

Swift version: 5.6. Index paths describe an item's position inside a table view or collection view, storing both its section and its position inside that section.


3 Answers

Ah Ha! I found the problem and am going to answer my own question for the poor soul who runs into this issue in the future.

All of my cells have variable height so I was using the new iOS7 method in UITableViewDelegate thinking it might speed up render time (not that I really needed it):

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;

Anyway, implementing this method has the evil side effect of causing the table to bounce to the top of the section when calling:

[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

To solve the bounce problem I just removed the override of that estimatedHeightForRowAtIndexPath method and now everything works as it should. Happy at last.

like image 67
xsee Avatar answered Oct 10 '22 17:10

xsee


This did the trick for me.

UIView.setAnimationsEnabled(false)
tableView.reloadRows(at: [...], with: .none)
UIView.setAnimationsEnabled(true)
like image 42
Giorgi Shavgulidze Avatar answered Oct 10 '22 16:10

Giorgi Shavgulidze


Swift 4.2

This can work anywhere you want to remove animation. During reload of table , table section or any row

 UIView.performWithoutAnimation({
                cell.configureSelection(isSelected: true)
                tableView.reloadSections([1], with: .none)
                tableView.allowsSelection =  false

            })
like image 4
Tanvir Singh Avatar answered Oct 10 '22 15:10

Tanvir Singh