ios - Swift iOS : how to trigger next page using buttons-LMLPHP

ios - Swift iOS : how to trigger next page using buttons-LMLPHP

我有一个 QuizViewController ,它扩展了 UIViewController UIPageControllerDelegateUIPageViewControllerDataSource

里面 QuizViewController.swift

private var pageViewController: UIPageViewController?

private func createPageViewController() {
       let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageViewController") as! UIPageViewController
       pageController.dataSource = self

       if pageInfo.count > 0 {
           let firstController = getItemController(0)!
           let startingViewControllers: NSArray = [firstController]
           pageController.setViewControllers(startingViewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
       }

       pageViewController = pageController
       addChildViewController(pageViewController!)
       self.view.addSubview(pageViewController!.view)
       pageViewController!.didMoveToParentViewController(self)
   }

   private func getItemController(itemIndex: Int) -> QuizPageItem? {
       if itemIndex < pageInfo.count {
           let CurrentQuizPageItem = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageItem") as! QuizPageItem
           CurrentQuizPageItem.itemIndex = itemIndex
           CurrentQuizPageItem.thisPageInfo = pageInfo[itemIndex]
           return CurrentQuizPageItem
       }

       return nil
   }

   /*
       PageView Delegates
   */
   func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {

       let CurrentQuizPageItem = viewController as! QuizPageItem

       if CurrentQuizPageItem.itemIndex > 0 {
           return getItemController(CurrentQuizPageItem.itemIndex - 1)
       }

       return nil
   }

   func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {

       let CurrentQuizPageItem = viewController as! QuizPageItem

       if CurrentQuizPageItem.itemIndex + 1 < pageInfo.count {
           return getItemController(CurrentQuizPageItem.itemIndex + 1)
       }

       return nil
   }

我的问题是如何使后退和后退按钮正常工作?

现在,可以通过滑动来更改页面。我不想使用滑动。我想使用“下一步”和“后退”按钮进行控制。

更新

ios - Swift iOS : how to trigger next page using buttons-LMLPHP

这是在Main.storyboard上

PageViewController是 Storyboard 中的中间一个。

PageViewController的 StoryboardID为 QuizPageViewController

QuizViewController是 Storyboard 中的左手。

QuizViewController使用 Storyboard ID 实例化PageViewController。QuizPageViewController

这是通过此块完成的
       let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageViewController") as! UIPageViewController
       pageController.dataSource = self

当实例化发生时,它还会为QuizPageItem创建首页。

QuizPageItem是Main.storyboard中最右边的 View 。

因此,如果您看到这两个模型,则它们都是QuizPageItems。

第一个模型的itemIndex应该为0。

第二个模型应具有1的itemIndex。
       let CurrentQuizPageItem = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageItem") as! QuizPageItem
       CurrentQuizPageItem.itemIndex = itemIndex

我收到的大多数答案都建议通过 QuizViewController (也就是Main.storyboard中最左侧的 View )来解决。

但是,这些按钮位于QuizPageItem中,无法通过QuizViewController访问。

我想知道如何连接QuizPageItem中的后退/下一步按钮以执行分页,这是在QuizViewController中控制的,假设我在Main.storyboard中连接各种 View 的方式是正确的

同时,我允许我在Main.storyboard中连接各种 View 的当前方式不太理想。

如果是这样,请建议另一种方法。

这是我遵循的教程,以了解我目前所处的位置。

http://shrikar.com/ios-swift-tutorial-uipageviewcontroller-as-user-onboarding-tool/

更新2
很抱歉,我被认为是在争论。我真的很想学习如何做到这一点。我很确定我缺乏一些基本知识,因此我无法理解迈克尔·道特曼的答案。

我假设QuizViewController中有一个函数将触发页面翻转。

我不确定该功能是什么。

我知道这些功能会在按下按钮时触发。

我在QuizPageItem类中具有以下内容
 @IBAction func pageBackButton(sender: AnyObject) {

 }

 @IBAction func pageNextButton(sender: AnyObject) {
 }

但是,它们不在QuizViewController类中,而在QuizPageItem类中。

我是否应该将setViewController方法放在QuizPageItem类的这两个函数中?

如果是这样,我什至如何从QuizPageItem类内部访问QuizViewController实例?

更新3:

我的文件结构是
  • QuizViewController.swift
  • QuizPageItem.swift

  • QuizViewController控制您看到哪个QuizPageItem。 QuizPageItem表示由模型设计的不同 View 。

    UPDATE4:

    matt的答案对我完全不熟悉的FirstResponder有所帮助,对我很有帮助。

    当我尝试实现它时,我遇到了这个错误。

    ios - Swift iOS : how to trigger next page using buttons-LMLPHP

    我在Google上四处搜寻,并试图对其进行补救,但无济于事。

    我一直触发此错误。

    随附的是QuizViewPageItemController.swift的代码段
    import UIKit
    class QuizPageItemViewController: UIViewController, CheckboxDelegate {
    
        @IBOutlet weak var pageHeadingLabel: UILabel!
        @IBOutlet weak var pageInstructionLabel: UILabel!
        @IBOutlet weak var pageProgressView: UIProgressView!
        @IBOutlet weak var pageQuestionLabel: UILabel!
        @IBOutlet weak var pageAnswerView: UIView!
        @IBOutlet weak var pageBackButton: UIButton!
        @IBOutlet weak var pageNextButton: UIButton!
        let pageNo: Int
        let maxPageNo: Int
        let thisPageInfo: [String]
    
        let interestsList = [
            "Blue Chips", "Small Caps", "Pharmaceuticals", "Agriculture",
            "Telecommunications", "Manufacturing", "Finance", "Banks",
            "Retail", "Travel", "Airlines", "Tourism"]
    
        init(pageNo: Int, maxPageNo: Int, thisPageInfo: [String]) {
            self.pageNo = pageNo
            self.maxPageNo = maxPageNo
            self.thisPageInfo = thisPageInfo
    
            super.init(nibName: nil, bundle: nil)
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.pageBackButton.hidden = pageNo == 0
            self.pageNextButton.hidden = pageNo == maxPageNo
            pageHeadingLabel.text = thisPageInfo[0]
            pageInstructionLabel.text = thisPageInfo[1]
            pageQuestionLabel.text = thisPageInfo[2]
    
            if thisPageInfo[0] == "Welcome" {
                createCheckboxes()
                pageProgressView.setProgress(0.33, animated: true)
            } else if thisPageInfo[0] == "Awesome!" {
                createSlider()
                pageProgressView.setProgress(0.67, animated: true)
            } else if thisPageInfo[0] == "Almost there..." {
                createSlider()
                pageProgressView.setProgress(0.95, animated: true)
            }
        }
    
        override func viewDidAppear(animated: Bool) {
            super.viewDidAppear(animated)
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func createCheckboxes() {
            let fWidth = (self.view.frame.width - 40) / 2
            var frame = CGRectMake(0, 0, fWidth, 40)
            var contentSize = CGRectMake(0, 0, self.view.frame.width - 40, 0)
    
            for (var counter = 0; counter < interestsList.count; counter++) {
                let checkbox = Checkbox(frame: frame, title: interestsList[counter], selected: false)
                checkbox.mDelegate = self
                checkbox.tag = counter
                checkbox.backgroundColor = UIColor.redColor()
    
                if counter % 2 == 0 {
                    frame.origin.x += fWidth
                } else{
                    frame.origin.x -= fWidth
                    frame.origin.y += frame.size.height
                    contentSize.size.height += frame.size.height
                }
    
                checkbox.titleLabel?.adjustsFontSizeToFitWidth = true
                pageAnswerView.addSubview(checkbox)
            }
        }
    
        func didSelectCheckbox(state: Bool, identifier: Int, title: String) {
            print("checkbox '\(title)' has state \(state)")
        }
    
        func createSlider() {
            let slider = UISlider(frame:CGRectMake(0, 20, self.view.frame.width - 40, 20))
            slider.minimumValue = 0
            slider.maximumValue = 10
            slider.continuous = true
            slider.tintColor = ChatQColours().chatQBlue
            slider.value = 5
            //        slider.addTarget(self, action: "sliderValueDidChange:", forControlEvents: .ValueChanged)
            pageAnswerView.addSubview(slider)
    
            let leftlabel = UILabel(frame: CGRectMake(0, 40, 0, 0))
            leftlabel.text = "Strongly Avoid"
            leftlabel.sizeToFit()
            pageAnswerView.addSubview(leftlabel)
    
            let rightlabel = UILabel(frame: CGRectMake(0, 40, 0, 0))
            rightlabel.text = "Strongly Prefer"
            rightlabel.sizeToFit()
            rightlabel.frame.origin.x = slider.frame.width - rightlabel.frame.width
            pageAnswerView.addSubview(rightlabel)
        }
    }
    

    最佳答案

    迈克尔·道特曼(Michael Dautermann)的答案是完全正确的,如以下截屏所示:

    ios - Swift iOS : how to trigger next page using buttons-LMLPHP

    您所看到的是一个具有多个页面的页面 View Controller (已编号,因此您可以看到顺序),每个页面都包含一个“下一步”按钮,而我反复按“下一步”按钮导航到下一页。

    与您的项目一样,如上截屏所示,我的项目具有 View Controller 层次结构:

  • UITabBarController
  • ViewController
  • UIPageViewController
  • 页面(具有主 View ,标签和按钮是该 View 的 subview )

  • 看来,您的问题的重点不是什么方法导致页面 View Controller 导航到其下一页或上一页—正如您已经被告知的那样,它只是setViewControllers:... —而是按钮如何与 View Controller 进行通信等级制度。在我的示例中,这意味着从页面 View 内的按钮发送消息,经过页面 View Controller ,经过UIPageViewController,最后到达ViewController,然后告诉UIPageViewController该做什么。

    我可以想到许多方法来做到这一点:
  • 该按钮发布一个通知,该通知已为其注册了ViewController
  • 该按钮发送一个目标为nil的 Action ,该 Action 的ViewController具有处理程序
  • 该按钮将消息发送到选项卡栏 Controller (其tabBarController属性),然后将消息向下发送到其当前选择的 View Controller ViewController
  • 该按钮向其 View Controller (在 Nib 或 Storyboard 中配置为 Action )发送一条消息,该 Controller 向其parentViewController!.parentViewController!(即ViewController)发送一条消息。

  • 我更喜欢哪一个?就我个人而言,我最喜欢以nil为目标的操作,因为它不需要任何额外的代码。唯一的func pageNextButton()实现在ViewController中。这就是针对零目标的 Action 的美:它沿着响应者链走,自动寻找接收者。在这方面,页面 View Controller 和UIPageViewController完全没有代码。

    我喜欢它比parentViewController!.parentViewController!好得多,因为ojit_code最终要求Page View Controller 知道它可以调用的ViewController中的方法的名称,并且必须将其转换为ViewController —它不是非常可移植的,并且提供了Page我认为,对 Controller 的环境了解过多。另一方面,对于目标为零的 Action ,发件人完全不知道实际的目标是谁!因此,我最喜欢无目标操作,而通知第二好。

    10-08 05:01