4
votes

I have a UIViewController subclass that contains a UICollectionView. Selecting a cell presents a new view controller. When I return to the first view controller, the contentOffset of the collection view is reset to CGPointZero.

From my research this seems to be standard behaviour.

I can reset the contentOffset by adding a private property to my view controller subclass, saving the contentOffset in the viewWillDissapear method and resetting it on the collection view in the viewWillAppear method.

I would like to know though, is there another way to prevent the scroll view content offset from being reset in the first place (removing the need for an extra property)?

I am targetting iOS7.

The 2nd view controller is presented like this:

[self presentViewController:secondVC animated:YES completion:nil];

And dismissed like this (in the 2nd view controller):

-(void) dismiss
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

Edit: After further investigation it appears resetting the contentOffset is not the default behaviour. I haven't figured out why it is happening in my application yet. I am presenting just as have showed in the code above.

3
Why do you want another method, I think this method works fineukim
For one thing I find this method messy. For another, when the contentOffset is reset to 0, the previously visible cells are reused. I am downloading images from a url, so when I go back to the view and reset the contentOffset, I need to redownload the images. This may not be an issue once I have proper caching in place, but I would still prefer this not happen.Darren
I don't see this behavior in my app (iOS 7.1). The content offset is not changed when I come back from a modal presentation. Are you using a segue connected to the cell or doing a manual presentation in didSelectItemAtIndexPath? If the latter, what code do you have in that method.rdelmar
@rdelmar: You're right. I created a test app and saw the same behaviour as you. I am presenting through the didSelectItemAtIndexPath method. I try to update my question.Darren
Are you reloading the data when you come back to the controller with the collection view?rdelmar

3 Answers

0
votes

There are 2 options. If your application works with UINavigationController, it should keep the last accessed cell, not sure about how you have worked with. If not, you can always create a notification and in the moment you are getting back to the previous screen, send the update of the UICollectionView or whatever you have and scroll to the correct position. Bear in mind, the UIViewController life cycle and how it´s going to appear before to update the user interface.

0
votes

You can create a CGPoint object in AppDelegate. Then you can set that value to your CollectionView objects contentOffset while present and dismiss like that;

[self presentViewController:secondVC animated:YES completion:{
    appDelegate.tempContentValue = _collectionView.contentOffset;
}];

[self dismissViewControllerAnimated:YES completion:{
    UIViewController *first = [UIViewController alloc] init];
    [first.collectionView setContentOffset:appDelegate.tempContentValue animated:YES];
}];
0
votes
   @property (nonatomic,assign) CGPoint newContentOffset;

Then when you navigate to another View / present another view

  self.newContentOffset = self.collectionView.contentOffset;

In viewWillAppear

  [self.collectionView reloadData];

   if (self.newContentOffset) {
        [self performSelector:@selector(setContentOffset) withObject:nil afterDelay:0.1];
   }


  -(void)setContentOffset {
        [self.collectionView setContentOffset:self.newContentOffset];

   }

There will be a small jerk while applying this . But if thats ok, you can go ahead with this method