Go to the next Page programmatically within a UIPageViewController

£可爱£侵袭症+ 提交于 2020-01-06 19:50:38

问题


I have a rootViewController which is basically my pageViewController which implements all the page controller protocol functions. I have already successfully implemented the whole pageViewController with a pageControl that correctly shows the current Page number.

On the first page contained within the rootViewController, I have a viewController in which there are multiple textFields which have to be filled in with a pickerView. I have also created an inputAccessory toolBar which accompanies the pickers. Once all the fields are filled with text, the barButton on the toolBar toggles to Done. On the tap of this 'Done' button, within this viewController, I want the rootViewController to go to the next page.

I first tried to directly present the viewController I wanted to turn to but noticed that the page was not presented as a part of the pageViewController(it seems pretty obvious why it didn't work now!). So I then tried to implement a protocol which would trigger the rootViewController to turn to the next page. I've implemented everything perfectly but the delegate is not being set. I can't seem to fathom why it isn't being set. Could this be because of something I may have missed in the UIPageViewController framework flow? I am stumped.

Ultimately in the protocol I am trying to communicate between a contained ViewController and the rootViewController.

Here is my source code:

In the rootController:

    import UIKit

    class rootPageViewController: UIViewController, UIPageViewControllerDataSource,
    UIPageViewControllerDelegate, tutorialPageTurnerDelegate {

        var tutorialOne = userInputViewController()

        @IBOutlet var pageLight: UIPageControl!

        var turn: UIPageViewController!
        let pages = ["userInput","tutorialOne","tutorialTwo","connectScreen"]
        var i: Int!

        override func viewDidLoad() {
            super.viewDidLoad()

            if let take = storyboard?.instantiateViewControllerWithIdentifier("pageView") {

                self.addChildViewController(take)
                self.view.addSubview(take.view)
                take.view.addSubview(pageLight)
                take.view.bringSubviewToFront(pageLight)

                turn = take as! UIPageViewController
                turn.dataSource = self
                turn.delegate = self

                // the delegate for the protocol I've implemented 
                tutorialOne.delegate = self

                turn.setViewControllers([viewControllerAtIndex(0)!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
                turn.didMoveToParentViewController(self)

            }

        }

       .
       .
       ... pageviewcontroller protocol functions and misc code ...
       .
       .

 // Helper Function to return Index
    func viewControllerAtIndex(index: Int) -> UIViewController? {

        let vc = storyboard?.instantiateViewControllerWithIdentifier(pages[index])

// _________EDIT_________
    if index == 0 {
                var tutorialOne: userInputViewController = userInputViewController()
                tutorialOne.delegate = self
            }
        return vc

    }


// function required by the protocol
func saveActionCompleted() {

        print("Yes it does come here")
        turn.setViewControllers([viewControllerAtIndex(1)!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
        turn.didMoveToParentViewController(self)

    }
...

Now here is the viewcontroller where I've created the protocol:

import UIKit
import CoreData

protocol tutorialPageTurnerDelegate {
    func saveActionCompleted()
}

class userInputViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate,
UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {


    var delegate: tutorialPageTurnerDelegate?

override func viewDidLoad() {
        super.viewDidLoad()

 //Create toolbar
                let toolBar = UIToolbar()
                toolBar.barStyle = UIBarStyle.Default
                toolBar.translucent = true
                toolBar.tintColor = UIColor(red: 81/255, green: 45/255, blue: 168/255, alpha: 1)
                toolBar.sizeToFit()

let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
                let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
                toolBar.setItems([spaceButton, nextButton], animated: false)
                toolBar.userInteractionEnabled = true

....... more misc code ...

}

// The selector function for the toolbar from where I want to notify the root controller
 func donePicker(){

        self.view.endEditing(true)
        saveDataAction(self)

        if delegate != nil {
            delegate!.saveActionCompleted()
        } else {
            print("PageTurnerDelegate is nil")
        }
     }
...
} //End

I'm getting PageTurnerDelegate is nil. I tried a bunch of workarounds but all in vain. I do get the feeling that there may be a better way of doing this. Any suggestions or insights are most welcome!


回答1:


You need to set the delegate property of the view controller instance that will be displayed:

func viewControllerAtIndex(index: Int) -> UIViewController? {

    let vc = storyboard?.instantiateViewControllerWithIdentifier(pages[index])
    if index == 0 {
            let userInputViewController =vc as! userInputViewController
            userInputViewController.delegate = self
    }
    return vc
}

Also, by convention, classes start with an upper case letter, so it should be UserInputViewController



来源:https://stackoverflow.com/questions/38330509/go-to-the-next-page-programmatically-within-a-uipageviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!