Earlier, I discussed how I set up a paged table view for The Hit List (now we've shipped, you can see this in action on the home screen!). And in my last blog post, we looked at state restoration for custom container view controllers.
Bringing the two together, how about adding state restoration to the paged table view controllers? Our setup looks like this:
There’s a custom VC, which contains a UIPageViewController. And then two table view controllers are loaded up by their ID to act as the pages.
Unlike UINavigationController, my poking and prodding suggests UIPageViewController doesn’t do any work of its own to handle state restoration. That’s our cue to step in.
We want to restore the user’s chosen tab, and that’s pretty straightforward:
But it’d also be nice if those table view controllers were to in turn restore their internal state: namely scroll point, and selected item.
Normally, the system takes care of this for us; assign a restoration identifier to the VC and the table (optionally implement UIDataSourceModelAssociation too), and restoration will kick in properly. However that’s not happening for us with the paged setup by default, I think again because we’re effectively implement a customer container view controller.
After experimenting, I came to the following conclusions:
- It doesn’t matter if the UIPageViewController instance has a restoration identifier or not
- Like before, we need to encode the table view controllers for state restoration to be applied to them
- It’s no good state restoration being applied if the recipient view controller isn’t then used! We need to decode the table view controllers and use them if possible, rather than creating fresh ones
I went with something like this:
Ideally you don’t waste time creating the view controllers, only to have state restoration overwrite that. I found that delaying creating the controllers until -viewWillAppear: provides a pretty decent solution to that. If the restored VCs are available, they get used; otherwise, fresh ones are created.