2

I am using setContentOffset on a UITableView because I want to initially hide a search field that is my tableHeaderView.

[self.tableView setContentOffset:CGPointMake(0, 56)]; // No scroll please!

Each time I push a new viewController I want to hide the search bar with contentOffset. But when I pop a viewController that offset is no longer in effect for some reason and shows the search bar. Why is this?

Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • 1
    I don't understand the question, the purpose of setContentOffset is to set the scroll position. – combinatorial Dec 09 '12 at 18:49
  • When I mean is, each time I push a new `viewController` I want to hide the search bar with contentOffset. But when I pop a `viewController` that offset is no longer in effect for some reason. Why is this? – Nic Hubbard Dec 09 '12 at 19:04
  • I would think that the answer from @nizx will work then. Reset the contentOffset every time the view is shown. – combinatorial Dec 09 '12 at 22:36

3 Answers3

0

you can try and implement it on the following

- (void)viewWillAppear:(BOOL)animated {
    [self.tableView setContentOffset:CGPointMake(0, 56)];
}

that will put the table in the correct position before it is displayed on the screen, I am assuming you mean no animation while setting the position.

nizx
  • 690
  • 1
  • 6
  • 13
  • This would work, but, say in VC1 they scroll to the bottom, then push a new VC by touching a cell. Then when they pop back, if I call `setContentOffset`, it will scroll the tableView to the top, even though it really should stay scrolled where the user had it. – Nic Hubbard Dec 10 '12 at 00:03
0

I am guessing that you want to stop the user being able to scroll to the very top of the screen. If so you can implement the following UITableView delegate (on iOS5 and above):

scrollViewWillEndDragging:withVelocity:targetContentOffset:

which allows you to modify the final target for a change in the contentOffset. In the implementation you do:

- (void)scrollViewWillEndDragging:(UIScrollView *)theScrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    if(targetContentOffset->y < 56) {
         targetContentOffset->y=56;
    }
}
combinatorial
  • 9,132
  • 4
  • 40
  • 58
0

If you are trying to preserve the value of something during an action that loses it, the natural solution is to hold onto it yourself ("Hold/Restore"):

  1. "Hold": get content offset to a field or local variable. Apple doc
  2. .. do whatever you want.
  3. "Restore": set content offset to the value you got above.

(Sorry, I don't write Objective C code, so can't provide the exact code. An edit to add the code, would be welcome.)


In a different situation, it might be necessary to hold the row you were at, and then scroll back to that row:
(Adapted from: https://stackoverflow.com/a/34270078/199364)

(Swift)
1. Hold current row.

let holdIndexPath = tableView.indexPathForSelectedRow()
  1. .. do whatever (perhaps ending with "reloadData").

  2. Restore held row:

// The next line is to make sure the row object exists.
tableView.reloadRowsAtIndexPaths([holdIndexPath], withRowAnimation: .None)
tableView.scrollToRowAtIndexPath(holdIndexPath, atScrollPosition: atScrollPosition, animated: true)
Community
  • 1
  • 1
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196