2

My problem is as follows: I am using pageViewControllers to create a tutorial/onboarding page for an app i'm creating. A left swipe gesture on the last (3rd) page of my tutorial should perform a segue.

This is what I have as of now, but it is giving me a key value coding-compliancy error. I have double, triple checked my outlets, and swipeView is very much so connected properly.

class GrowController: UIViewController {

@IBOutlet weak var swipeView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(swipeView)
    createGesture()

}

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

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

That is the controller for the actual UIViewController (the specific page that is being displayed)

now ive also tried messing around with some logic in my TutorialViewController which is the UIPageViewController controlling the swipes form page to page etc.

Logic for that here

class TutorialViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

var viewControllerIndex: Int?

//Array of my pages to load (GrowController is page3)
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()

    self.dataSource = self
    self.delegate = self

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

// Scroll view
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    for view in self.view.subviews {
        if view is UIScrollView {
            view.frame = UIScreen.main.bounds 
        }
        else if view is UIPageControl {
            view.backgroundColor = UIColor.clear
        }
    }
}


// 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 {
// Added this line just testing around, nothing happened here though.
        performSegue(withIdentifier: "ShowRegister", sender: self)
        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
    }


}

Does is have something to do with the willTransitionTo pageView delegate method? I'm not familiar how to implement that, I have tried.

I thought that i could just add a subView to the Grow controller, put a swipe gesture in it, and perform a segue whenever the user swipes left from that page. As of right now, this code crashes the app upon loading of page3 (GrowController)

Any help GREATLY appreciated, I've been trying to figure this out for over a week and this is the second question on the topic i've posed. Thanks!

enter image description here

Dan
  • 792
  • 1
  • 7
  • 17
  • Let me just check that I understand what you want to do. You want the user to be able to swipe-swipe-swipe to get thru the three pages of the page view controller, and then if the user goes swipe again, we segue right out of here? Is that correct? – matt Jan 31 '17 at 19:33
  • Exactly! except that it starts on page one, and its just swipe-swipe, and then the third swipe from page3 will segue out! but yes thats the exact concept – Dan Jan 31 '17 at 19:34
  • Are the segues properly attached from the GrowController to the next controller? (via storyboard or programmatically). Also, could you post the actual error logs that you get. – Mark Barrasso Jan 31 '17 at 19:38
  • mark, yes the segues are properly connected and above is now an image of my actual error log - I have never seen/set `speed` or `speedVariance`, and cannot find either written anywhere programatically in any code -.- Will try the answer below now matt! – Dan Jan 31 '17 at 19:46

1 Answers1

0

Don't use a UIPageViewController for this. That's very ironic, because I am usually the first to advise using UIPageViewController. But in this case it is doing too much of the work for you, and you cannot interfere in such a way as to customize it the way you're describing. You will need to use a simple paging UIScrollView; that way, you will be totally in charge of what happens, with fine-grained response thanks to the scroll view's delegate, and you'll have access to the underlying pan gesture recognizer and can modify its behavior.

matt
  • 515,959
  • 87
  • 875
  • 1,141