Search code examples
iosswiftxcodeswift3uipageviewcontroller

Perform segue from onboarding / tutorial screen


I am using the UIPageViewController for an on boarding / tutorial screen, and my problem is as follows:

When the user is on the last page of the tutorial, i want a left swipe gesture not to try and swipe the page controller, but instead to perform a segue to the registration page. I threw a print statement into the viewDidLoad in the UIViewController for the last page of the tutorial, and it registers.

In that same viewDidLoad I create my gestures to perform the segue, but nothing happens. I even tried putting the performSegue inside of the viewDidLoad, but nothing happened. I have my segue connected to the UIPageViewController as well as my GrowController, and neither register. I'm at a loss!

This is the UIViewController for the last page of tutorial

class GrowController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    print("*********************************")
    createGesture()
    // performSegue(withIdentifier: "ShowRegister", sender: self)
}


func createGesture() {
    let showReg = UISwipeGestureRecognizer(target: self, action: #selector(showRegister))
    showReg.direction = .left
    view.addGestureRecognizer(showReg)
}


func showRegister(gesture: UISwipeGestureRecognizer) {
    performSegue(withIdentifier: "showRegister", sender: self)
}

}

This is the UIPageViewController that handles the tutorial logic

class TutorialViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

    var viewControllerIndex: Int?

lazy var tutorialArray: [UIViewController] = {
    return [self.tutorialInstance(name: "page1"), self.tutorialInstance(name: "page2"), self.tutorialInstance(name: "page3")]
}()


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



override func viewDidLoad() {
    super.viewDidLoad()
    if let image = UIImage(named: "export.png") {
        view.backgroundColor = UIColor.init(patternImage: image)
    } else {
        print("Error")
    }

    self.dataSource = self
    self.delegate = self

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

These are the delgate and datasource functions

// Page View Controller delegate functions
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    guard let viewControllerIndex = tutorialArray.index(of: viewController) else {
        return nil
    }

    let previousIndex = viewControllerIndex - 1

    guard previousIndex >= 0 else {
            return nil
    }

    guard tutorialArray.count > previousIndex else {
        performSegue(withIdentifier: "ShowRegister", sender: self)  // Added this line just testng around, nothing happend here though.
        return nil
    }

    return tutorialArray[previousIndex]
}


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

    let nextIndex = viewControllerIndex + 1

    guard nextIndex < tutorialArray.count else {
        return nil
    }

    guard tutorialArray.count > nextIndex else {
        return nil
    }

    return tutorialArray[nextIndex]
}

public func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return tutorialArray.count
}

public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
    guard let firstViewController = viewControllers?.first, let firstViewControllerIndex = tutorialArray.index(of: firstViewController) else {
        return 0
    }
    return firstViewControllerIndex
}

Lots of code for what is probably a simple answer.

tl;dr - How can I make a swipe gesture perform a segue from a specific page of the UIPageViewController


Solution

  • There is a delegate method that you can implement pageViewController(_:willTransitionTo:) but I don't know that its worth the trouble. Maybe just put another view in front of it and put a swipe gesture recognizer view in that view and use the gesture recognized to manually change the page or segue to the new controller.