Swift iOS:如何使用按钮触发下一页

Kim*_*cks 6 pageviews ios uipageviewcontroller swift

在此输入图像描述

在此输入图像描述

我有一个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
   }
Run Code Online (Sandbox Code Playgroud)

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

现在可以通过滑动更改页面.我不想使用滑动.我想使用next和back按钮进行控制.

UPDATE

在此输入图像描述

这是在Main.storyboard上

PageViewController是故事板中的中间部分.

PageViewController的故事板ID为QuizPageViewController.

QuizViewController是故事板中的左侧.

QuizViewController使用storyboard id QuizPageViewController实例化一个PageViewController

这是由这个块完成的

       let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageViewController") as! UIPageViewController
       pageController.dataSource = self
Run Code Online (Sandbox Code Playgroud)

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

QuizPageItem是Main.storyboard中最右侧的视图.

因此,如果你看到2个模型,它们都是QuizPageItems.

第一个模型应该有一个itemIndex为0.

第二个模型的itemIndex为1.

       let CurrentQuizPageItem = self.storyboard!.instantiateViewControllerWithIdentifier("QuizPageItem") as! QuizPageItem
       CurrentQuizPageItem.itemIndex = itemIndex
Run Code Online (Sandbox Code Playgroud)

我收到的大多数答案建议通过QuizViewController(也就是我的Main.storyboard中最左边的视图)来解决它.

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

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

与此同时,我允许我在Main.storyboard中连接各种视图的当前方式的可能性并不理想.

如果是这样,请提供另一种方法.

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

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

更新2 我道歉,我被视为争论.我真的想学习如何做到这一点.我很确定我缺乏一些基础知识,因此我无法理解Michael Dautermann的答案.

我假设QuizViewController中有一个函数会触发翻页.

我不确定那个功能是什么.

这些是我知道按下按钮时触发的功能.

我在QuizPageItem类中有以下内容

 @IBAction func pageBackButton(sender: AnyObject) {

 }

 @IBAction func pageNextButton(sender: AnyObject) {
 }
Run Code Online (Sandbox Code Playgroud)

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

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

如果是这样,我如何从QuizPageItem类中访问QuizViewController实例?

更新3:

我的文件结构是

  • QuizViewController.swift
  • QuizPageItem.swift

QuizViewController控制您看到的QuizPageItem.QuizPageItem表示由模型设计的不同视图.

UPDATE4:

matt的回答帮助了我很多,因为我首先理解了这个我完全不熟悉的FirstResponder.

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

在此输入图像描述

我已经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)
    }
}
Run Code Online (Sandbox Code Playgroud)

mat*_*att 16

Michael Dautermann的回答是完全正确的,因为这个截屏视频显示:

在此输入图像描述

您所看到的是具有多个页面的页面视图控制器(编号以便您可以看到订单),每个页面都包含"下一步"按钮,并且我反复按"下一步"按钮导航到下一页.

和你的一样,我的项目,如上面的截屏视频所示,有一个视图控制器层次结构:

  • 的UITabBarController

  • 视图控制器

  • UIPageViewController

  • 页面(具有主视图,标签和按钮是其子视图)

您的问题的核心似乎不是什么方法导致页面视图控制器导航到其下一页或上一页 - 正如您已经被告知的那样,这只是setViewControllers:...- 但按钮如何与视图控制器层次结构通信.在我的例子中,这意味着从Page的视图中的按钮发送消息,经过Page视图控制器,经过UIPageViewController,然后到ViewController,然后告诉UIPageViewController做什么.

我可以想出很多方法来做到这一点:

  • 该按钮发布ViewController注册的通知

  • 该按钮发送一个nil-targeted动作,ViewController有一个处理程序

  • 该按钮将消息发送到标签栏控制器(其tabBarController属性),其接着发送一个消息向下到其当前选择的视图控制器,所述的ViewController

  • 该按钮向其视图控制器(在笔尖或故事板中配置为动作)发送消息,该消息向其发送消息parentViewController!.parentViewController!,即ViewController.

我更喜欢哪一个?就个人而言,我最喜欢无目标的动作,因为它不需要额外的代码.唯一的func pageNextButton()实现是在ViewController中.这是一个无针对性的行动之美:它走了响应链,寻找收件人,自动.在这方面,页面视图控制器和UIPageViewController根本没有代码.

我比这更喜欢这个parentViewController!.parentViewController!,因为后者最终要求Page视图控制器知道它可以调用的ViewController中的方法名称,并且它必须转换为ViewController - 它不是非常便携并且给出了Page视图在我看来,控制器对其环境的了解太多了.另一方面,如果没有针对性的行动,发送者完全不知道实际目标将会是谁!所以我最喜欢nil-target动作,并且通知次之.

  • 如果你仍然没有得到它,我已经在github上发布了示例项目:https://github.com/mattneub/pageViewControllerUsingInternalButtons (7认同)

Raj*_*ain 11

Swift 3.0

这里非常简单的解决方案

要从UIViewController更改页面(UIViewController),首先获取Parent ViewController的实例(将是UIPageViewController),然后设置其当前的ViewController

在我的情况下,我有一个名为"UserDetailsPVC"的UIPageViewController,它包含4个页面(UIViewControllers),如下所示

  PageOneVC:UIViewController
  PageTwoVC:UIViewController
  PageThreeVC:UIViewController
  PageFourVC:UIViewController
Run Code Online (Sandbox Code Playgroud)

在UIPageViewController中,我们定义一个页面数组

 var pages:[UIViewController] = [
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PageOneVC"),
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PageTwoVC"),
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PageThreeVC"),
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PageFourVC")
]
Run Code Online (Sandbox Code Playgroud)

现在从任何UIViewController更改UIPageViewController的页面

    // get parent view controller
    let parentVC = self.parent as! UserDetailsPVC

    // change page of PageViewController
    parentVC.setViewControllers([parentVC.pages[1]], direction: .forward, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)


Mic*_*ann 7

您可以用来setViewControllers:direction:animated:completion:编程方式翻页.

只需传递上一页或下一页的视图控制器即可.


归档时间:

查看次数:

22438 次

最近记录:

6 年,9 月 前