ios 将 UIPageViewController 与 swift 和多个视图控制器一起使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25387436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:55:50  来源:igfitidea点击:

Using UIPageViewController with swift and multiple view controllers

iosswiftuipageviewcontroller

提问by Stone Preston

I'm trying to utilize a UIPageViewControllerin a Swift app with multiple view controllers. I have 2 view controllers on my storyboard (firstViewControllerand secondViewController) that are both embedded in their own navigation controllers. They have storyboard identifiers "FirstViewController" and "SecondViewController". I also have a page view controller on my storyboard with identifierPageViewcontroller and set the navigation to horizontal and transition style to scroll in the attributes inspector. FirstViewControlleris the root view controller of the app

我正在尝试UIPageViewController在具有多个视图控制器的 Swift 应用程序中使用 a 。我的故事板(firstViewControllersecondViewController)上有 2 个视图控制器,它们都嵌入在它们自己的导航控制器中。他们有故事板标识符“ FirstViewController”和“ SecondViewController”。我的故事板上还有一个带有identifierPageView控制器的页面视图控制器,并将导航设置为水平和过渡样式以在属性检查器中滚动。FirstViewController是应用程序的根视图控制器

I want firstViewControllerto be the first page of the page view controller so I have written its class like so:

我想firstViewController成为页面视图控制器的第一页,所以我写了这样的类:

import Foundation
import UIKit

class FirsttViewController: UITableViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate  {

    override func viewDidLoad() {

        let pageViewController: PageViewController = self.storyboard.instantiateViewControllerWithIdentifier("PageViewController") as PageViewController

        pageViewController.delegate = self

        var viewControllers: [UIViewController] = [self]

        pageViewController.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
        pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)

        self.addChildViewController(pageViewController)
        self.view.addSubview(pageViewController.view)
        pageViewController.didMoveToParentViewController(self)


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


        let secondViewController: SecondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController


        return secondViewController
    }

    func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {

        return nil
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return 2
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return 0
    }
}

the file for SecondViewControllerlooks like this:

文件SecondViewController看起来像这样:

import Foundation
import UIKit

class SecondViewController: UITableViewController, UIPageViewControllerDataSource {

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

        return nil
    }

    func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {

        let firstViewController: FirstViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
        return firstViewController
    }

}

However, when I run my app it doesn't seem to have a page view controller. It just shows firstViewControllerand that's it. No dots, no pages, etc. Anyone know whats wrong? I've found a couple of Objective-C tutorials but they all cover using one view controller for all the pages and have a root view controller that is not a page in the pageViewso they weren't too much help. I was hoping it was going to be like using a tabBarControllerwhere you just click and drag to the view controllers but thats not the case unfortunately. like I said I've not worked with one of these before so I'm sort of lost.

但是,当我运行我的应用程序时,它似乎没有页面视图控制器。它只是显示firstViewController,仅此而已。没有点,没有页面等。有人知道出了什么问题吗?我找到了一些 Objective-C 教程,但它们都涵盖对所有页面使用一个视图控制器,并且有一个不是页面中的根视图控制器,pageView因此它们没有太大帮助。我希望它就像使用一个tabBarController你只需点击并拖动到视图控制器的地方,但不幸的是事实并非如此。就像我说的那样,我以前没有使用过其中一个,所以我有点迷茫。

update:

更新:

following iiFreeman's suggestion, I subclassed UIPageViewControllerand made it the root in my storyboard file. below is the subclass

按照 iiFreeman 的建议,我UIPageViewController将其子类化并使其成为我的故事板文件中的根。下面是子类

import Foundation
import UIKit
class PageViewController: UIPageViewController {

    override func viewDidLoad() {

        let startingViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController

        self.dataSource = startingViewController
        var viewControllers: [UIViewController] = [startingViewController]

        self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)



    }

}

However now the app just hangs on a black screen and eventually Xcode loses connection to the simulator. I'm not really sure what's up.

但是现在应用程序只是挂在黑屏上,最终 Xcode 失去了与模拟器的连接。我不太确定这是怎么回事。

回答by Stone Preston

OK, I got it figured out. since I needed the page view controller to be the root and handle everything, I subclassed UIPageViewControlleras iiFreeman suggested and conformed to the delegate and data source protocols. I then set up the controller in viewDidLoad, and implemented the delegate and data source methods. I added a property store an array of storyboard identifiers as well as one to keep track of the current index of that array. I also added a helper method to return the correct view controller given an index. I didn't need anything in my other tableViewcontroller subclasses since my page view controller was handling everything. One thing I did realize is since my tableViewControllers were embedded in navigation controllers, my page view controller actually needed to show the navigation controllers, not the tableViewcontrollers. below is my implementation:

好的,我明白了。因为我需要页面视图控制器作为根并处理所有事情,所以我UIPageViewController按照 iiFreeman 的建议进行了子类化,并符合委托和数据源协议。然后我在 中设置了控制器viewDidLoad,并实现了委托和数据源方法。我添加了一个属性存储故事板标识符数组以及一个跟踪该数组的当前索引的属性。我还添加了一个辅助方法来返回给定索引的正确视图控制器。我的其他tableView控制器子类中不需要任何东西,因为我的页面视图控制器正在处理所有事情。我确实意识到的一件事是因为我的tableViewControllers 嵌入在导航控制器中,我的页面视图控制器实际上需要显示导航控制器,而不是tableView控制器。下面是我的实现:

import Foundation
import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var index = 0
    var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
    override func viewDidLoad() {

        self.dataSource = self
        self.delegate = self

        let startingViewController = self.viewControllerAtIndex(self.index)
        let viewControllers: NSArray = [startingViewController]
        self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)



    }

    func viewControllerAtIndex(index: Int) -> UINavigationController! {

        //first view controller = firstViewControllers navigation controller
        if index == 0 {

            return self.storyboard.instantiateViewControllerWithIdentifier("FirstNavigationController") as UINavigationController

        }

        //second view controller = secondViewController's navigation controller
        if index == 1 {

            return self.storyboard.instantiateViewControllerWithIdentifier("SecondNavigationController") as UINavigationController
        }

        return nil
    }
    func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier)

        //if the index is the end of the array, return nil since we dont want a view controller after the last one
        if index == identifiers.count - 1 {

            return nil
        }

        //increment the index to get the viewController after the current index
        self.index = self.index + 1
        return self.viewControllerAtIndex(self.index)

    }

    func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier)

        //if the index is 0, return nil since we dont want a view controller before the first one
        if index == 0 {

            return nil
        }

        //decrement the index to get the viewController before the current one
        self.index = self.index - 1
        return self.viewControllerAtIndex(self.index)

    }


    func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return self.identifiers.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return 0
    }

}

this post helped me out a lot

这篇文章帮了我很多

回答by iiFreeman

sure cause FirstViewController - initial view controller in your storyboard

肯定会导致 FirstViewController - 故事板中的初始视图控制器

add a custom UIPageViewController subclass into your storyboard, mark it as initial and do all work inside, instantiate page controller members by storyboardIDs in your UIPageViewController subclass, do the same thing just inside another class

将自定义 UIPageViewController 子类添加到您的故事板中,将其标记为初始并在内部完成所有工作,通过 UIPageViewController 子类中的 storyboardID 实例化页面控制器成员,在另一个类中执行相同的操作

回答by Sebastian Serrano

Please be aware that this code will only work with two ViewController. If you are planning on using more you have to change the line:

请注意,此代码仅适用于两个ViewController. 如果您打算使用更多,则必须更改该行:

self.index = self.index + 1

Found at the before and after call, to:

在通话前后找到,到:

self.index = index + 1

To call the current ViewControllerindex.

调用当前ViewController索引。