Kex
Kex

Reputation: 8609

UIPageViewController and saving the state of the UIViewControllers

I am pretty new to UIPageViewControllers. I have setup one that can page through different types of UIViewControllers.

I have noticed that when I scroll back to a previous one all the data and states are reset (i.e. I previously changed the UIViewController background color and it has reset back to default). I am using restoration IDs from the story board to initiate these controllers.

If I am using these shouldn't it save the state of the controller?

Code for changing controllers:

#pragma mark - UIPageViewControllerDataSource

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{

    //This is nice and avoids having to use a counter
    NSString *vcRestorationID = viewController.restorationIdentifier;
    NSUInteger index = [self.controllerRestorationIDs indexOfObject:vcRestorationID];

    if (index == 0) {
        return nil;
    }

    return [self viewControllerAtIndex:index - 1];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSString *vcRestorationID = viewController.restorationIdentifier;
    NSUInteger index = [self.controllerRestorationIDs indexOfObject:vcRestorationID];

    //Don't allow it to go forward if there is one at the end
    if (index == self.controllerRestorationIDs.count - 1) {
        return nil;
    }

    return [self viewControllerAtIndex:index + 1];
}


#pragma mark - Private Methods

- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
    // Only process a valid index request.
    if (index >= self.controllerRestorationIDs.count) {
        return nil;
    }

    // Create a new view controller.
    BaseContentViewController *contentViewController = (BaseContentViewController *)[self.storyboard instantiateViewControllerWithIdentifier:self.controllerRestorationIDs[index]];

    // Set any data needed by the VC here
    contentViewController.rootViewController = self;

    return contentViewController;

}

Is there a way to do this so the state is saved and the controllers aren't reloaded every time?

Upvotes: 0

Views: 664

Answers (1)

Maen
Maen

Reputation: 10698

This behavior happens because you instanciate a new view controller each time you access it.

To solve this :

  • you can cache the view controllers : store them in a global mutable array of your page view controller, and check each time the page view controller asks its data source for a view controller, add it to the global array or retrieve it if it's already in there.
  • use class variables instead of instance variables for the properties you change in the view controllers.

The first solution is volatile : whenever the pageVC is deallocated, you'll lose the modification made to the view controllers. The second one is more sure.

Upvotes: 1

Related Questions