b3rge
b3rge

Reputation: 5009

How do I keep scroll position when navigating in a navigation controller?

have been looking around, but I have not found an answer that helped me out. I am wondering how I can keep the scroll position in a scrollview when I move forwards and backwards in a navigation controller. Currently, when I go to another view in the navigation controller, the scroll view resets and is at the top when I go back. Any code would be greatly appreciated. Sorry if my explanation was not good enough. So far this is what I have, I know that this won't work, but what should I do?

- (void)viewWillAppear:(BOOL)animated {
    scrollView.contentOffset.y = scrollSave;
    [super viewWillAppear:YES];
}

- (void)viewWillDisappear:(BOOL)animated {
    CGFloat scrollSave = scrollView.contentOffset.y;
    [super viewWillDisappear:animated];
}

Upvotes: 2

Views: 914

Answers (3)

Steven Ritchie
Steven Ritchie

Reputation: 228

Kyle's answer should get you storing the variable okay, but in regards to assigning the contentOffset.y, trying animating the scrollview.

[scrollView scrollRectToVisible:
CGRectMake(scrollView.frame.origin.x, scrollSave.y, scrollView.frame.size.width, scrollView.frame.size.height) 
animated:NO];

That code would go into viewWillAppear.

Upvotes: 0

Kyle C
Kyle C

Reputation: 4097

With your current approach, scrollSave is a local variable declared in viewWillDisappear so you cannot access the value in viewWillAppear. You will need to create an instance variable or a property. (If the view controller is still in memory, it should maintain the contentOffset so this might not be necessary)

 @interface MyViewController ()
   @property (nonatomic) CGPoint scrollSave;
 @end

 @implementation MyViewController
 - (void)viewWillAppear:(BOOL)animated {
   [scrollView setContentOffset:self.scrollSave];
   [super viewWillAppear:YES];
 }

 - (void)viewWillDisappear:(BOOL)animated {
   self.scrollSave = scrollView.contentOffset;
   [super viewWillDisappear:animated];
 }

Now there is an issue with persistence. If the you navigate back in the navigation controller, this view controller will be released from memory. If you need to save the users position then I would suggest using NSUserDefaults.

 @interface MyViewController ()
   @property (nonatomic)  NSUserDefaults *defaults
 @end

 @implementation MyViewController
 - (void)viewWillAppear:(BOOL)animated { 
   CGPoint scrollSave = CGPointFromString([_defaults objectForKey:@"scrollSaveKey"]);
   scrollView.contentOffset = scrollSave;
   [super viewWillAppear:YES];
 }

 - (void)viewWillDisappear:(BOOL)animated {
   [_defaults setObject:NSStringFromCGPoint(scrollView.contentOffset) forKey:@"scrollSaveKey"];
   [_defaults synchronize];
   [super viewWillDisappear:animated];
 }

Upvotes: 0

Gavin
Gavin

Reputation: 8200

The code you have above shouldn't even compile. You could save this scroll position in another variable, but generally the scroll position shouldn't be resetting itself anyway. You should remove any code that is trying to manipulate the content offset at all, and see if it restores it to the correct scroll position upon returning to the view.

Upvotes: 1

Related Questions