Selch
Selch

Reputation: 131

Stop tableView from scrolling

I'm not sure this is possible but here's my scenario: I have this tableView with 3 sections. If you touch the white star in the 3rd section on accessoriesImage, it will insert that row to the Favorites section, just like accessories.sku. That works just fine.

Now, when you add rows to Favorites the Favorites section grows larger and pushes the third section down the screen. I understand that it obviously needs to do this when adding rows to section two. However, that last section has 400+ rows in it and you can very quickly scroll the top two sections off the screen, it's here that I want to stop scrolling.

What happens is, you scroll down looking at the rows in section 3 and the top two sections are way off the visible screen. Then you touch the star on a row to add a new favorite, this triggers that row to be inserted into section 2, the favorites section. But it also pushes down your current view down by one row when it does that insertion. I understand when the Favorites section is visible that this would be unavoidable, but when that section is off the screen I don't want to see my rows get pushed down because of the insertion.

The second image below may help explain that more. Here, we've scrolled way down the screen. If I click a star to add a favorite, it inserts a row way up in section 2 and pushes the rows you see in that image down one row. I just want to keep those rows in place when it does the insertion above.

I'd love to hear your ideas. Thanks.

enter image description here

enter image description here

Upvotes: 1

Views: 1163

Answers (1)

Anton
Anton

Reputation: 4018

First, I would urge you to consider a design that doesn't have so much repetitive information shown to the user on the same screen--it will make your app more intuitive. For example, have an option that toggles all non-favorited rows. This way, you can show all rows and select favorites, or hide them if you want to only choose from favorites.

Second, if you decide to keep this design, I suggest you scroll the table view down while the new row is being inserted, rather than trying to stop the scrolling caused by the insertion. To the user, this will seem as through no scrolling occurred. Here's how:

The UITableView has a ContentOffset property, which is a CGPoint. This point's y property is a CGFloat indicating how far down the table view is scrolled. So, in your code, when you're adding a row, simultaneously scroll down the screen too:

// I use some variables for illustrative purposes here (you will need to provide them from your existing code):

// *** put your code to add or remove the row from favorites to your table view data source here ***

// start animation queue
[UIView beginAnimations:nil context:nil];
// check if a row is being added or deleted
if (isAddingRow) {
    // if added, call to insert the row into the table view
    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:insertedIndexPath] withRowAnimation:UITableViewRowAnimationFade];
    // also tell the table view to scroll down the height of a row
    [tableView setContentOffset:CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y + kHeightOfRow) animated:YES];
} else {
    // if deleted, call to delete the row into the table view
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:deletedIndexPath] withRowAnimation:UITableViewRowAnimationFade];
    // also tell the table view to scroll down the height of a row
    [tableView setContentOffset:CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y - kHeightOfRow) animated:YES];
}
// launch animations
[UIView commitAnimations];

Alternately, if you're not using animations when a row is selected, you can actually turn off animations (does the same as above without any animations):

// check if a row is being added or deleted
if (isAddingRow) {
    // if added, call to insert the row into the table view
    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:insertedIndexPath] withRowAnimation:UITableViewRowAnimationNone];
    // also tell the table view to scroll down the height of a row
    [tableView setContentOffset:CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y + kHeightOfRow) animated:NO];
} else {
    // if deleted, call to delete the row into the table view
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:deletedIndexPath] withRowAnimation:UITableViewRowAnimationNone];
    // also tell the table view to scroll down the height of a row
    [tableView setContentOffset:CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y - kHeightOfRow) animated:NO];
}

You'll also want to perform the setContentOffset:animated: method only when the table view contentSize is (or will become) larger than the tableView size. Hope that helps!

Upvotes: 3

Related Questions