Austin Berenyi
Austin Berenyi

Reputation: 1053

How do I navigate forward and backward within UIPageViewController using buttons?

I'm creating an onboarding app for New Patients of a physical therapy clinic. The new patient will answer questions on each view controller within the UIPageViewController and tap a button to go to the next question.

I followed a tutorial and set up my UIPageViewController PageVC along with 3 view controllers. PageVC currently changes pages by swiping, but I want to be able to navigate backward and forward through view controllers using two buttons that are subviews of PageVC itself. How do I accomplish this?

I like using UIPageViewController and want to understand it a bit more. If there is a more effective method besides using UIPageViewController to accomplish this same task I'm happy to consider it.

    class PageVC: UIPageViewController, UIPageViewControllerDataSource {

        private(set) lazy var orderedViewControllers: [UIViewController] = {
            return [self.VCInstance(name: "BodyChart"),
                    self.VCInstance(name: "Symptoms"),
                    self.VCInstance(name: "HadSurgery")]
        }()

        private func VCInstance(name: String) -> UIViewController {
            return UIStoryboard(name: "Main", bundle: nil) .
                instantiateViewController(withIdentifier: name)
        }

        func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
            guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
                return nil
            }

            let previousIndex = viewControllerIndex - 1

            guard previousIndex >= 0 else {
                return nil
            }

            guard orderedViewControllers.count > previousIndex else {
                return nil
            }

            return orderedViewControllers[previousIndex]
        }

        func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
            guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
                return nil
            }

            let nextIndex = viewControllerIndex + 1
            let orderedViewControllersCount = orderedViewControllers.count

            guard orderedViewControllersCount != nextIndex else {
                return nil
            }

            guard orderedViewControllersCount > nextIndex else {
                return nil
            }

            return orderedViewControllers[nextIndex]
        }

        override func viewDidLoad() {
            super.viewDidLoad()

            dataSource = self

            if let firstViewController = orderedViewControllers.first {
                setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil)
            }
        }

 }

Upvotes: 0

Views: 1794

Answers (1)

jnblanchard
jnblanchard

Reputation: 1200

I think what you're looking for is here. But this is another way.

UIPageViewController has an instance method transition. The snippet below will move from the first to the second page child view controller.

pageViewController.transition(from: pageViewController.viewControllers[0], to: pageViewController.viewControllers[1], duration: 0.3, options: UIViewAnimationOptions.curveEaseInOut, animations: nil, completion: nil)

PageVC currently changes pages by swiping, but I want to be able to navigate backward and forward through view controllers using two buttons

Add your buttons to page content, then disable horizontal scrolling on PageVC's scrollview or disable views' user interaction in a mannered fashion.

Upvotes: 1

Related Questions