Search code examples
iosswiftuipageviewcontrollerviewdidappear

UIPageViewController jump directly to page causes issues with instance variables


I'm rather new to Swift, having coded in JavaScript so much more, so I must be missing something subtle here. I have a UIPageViewController that controls 3 pages, and each page has a particular instance variable that is being set by the parent UIPageViewController. Let's call that instance variable currentState. I also have a function that allows the user to jump directly into any of the pages. However, for some reason, when the user jumps directly to that page, the instance variable currentState seems to not have been set when calling viewDidAppear, even though it is detected in other parts of the page code.

This is the code to jump to a page, and pass in the state:

func goToPage(index: Int)
    {
        if index < viewControllers!.count
        {
            let destViewController = viewControllers![index]
            (destViewController as! WorkflowController).currentState = DataStore.sharedStore.state
            setViewControllers([destViewController], direction: .forward, animated: true, completion: nil)
        }
    }

In the viewDidAppear for the destination page, test code indicates that the state is not set, even though it is properly set when the user scrolls through to the page without jumping:

override func viewDidAppear(_ animated: Bool)
{
        if let state = currentState
        {
            // Happens when user scrolls page by page until this one
            print("State variable loaded")
        }
        else
        {
            // Happens when user jumps to page
            print("State variable did NOT load")
        

        }
}

What am I missing in the setup?


Solution

  • I solved my problem. Due to my newness to Swift (never mind UIPageViewController), the actual "jump to a page" is being done elsewhere, not in the goToPage code that was posted above. It's actually in the UIPageViewController's viewDidLoad section, as follows. The solution is to make sure all the instance variables of the destination controller are all set BEFORE you call setViewControllers function to do the "jump":

     override func viewDidLoad() {
        super.viewDidLoad()
        
        
        dataSource = self
        
        // This is where we do a jump, if current page isn't the first page
        if currentPage != 0
        {
            
            let firstViewController = orderedViewControllers[currentPage]
            (firstViewController as! WorkflowController).currentState = DataStore.sharedStore.state
            (firstViewController as! WorkflowController).delegate = self
            
            setViewControllers([firstViewController],
                               direction: .forward,
                               animated: true,
                               completion: nil)
            
            
         
            
            return
        }
    
       // more code is omitted...
    }