使用带有swift和多个视图控制器的UIPageViewController

时间:2014-08-19 15:32:58

标签: ios swift uipageviewcontroller

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

我希望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
    }
}

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
    }

}

然而,当我运行我的应用程序时,它似乎没有页面视图控制器。它只显示firstViewController及其相关内容。没有点,没有页面等。任何人都知道什么是错的?我找到了几个Objective-C教程,但它们都覆盖了所有页面使用一个视图控制器,并且有一个根视图控制器,它不是pageView中的页面所以它们不是太多的帮助。我希望它会像使用tabBarController,只需单击并拖动到视图控制器,但不幸的是不是这样。就像我说的那样我以前没有和其中一个合作过,所以我有点失落。

更新

根据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)



    }

}

然而现在应用程序只挂在黑屏上,最终Xcode失去了与模拟器的连接。我不确定是什么。

3 个答案:

答案 0 :(得分:32)

好的,我明白了。因为我需要页面视图控制器作为根并处理所有内容,所以我将UIPageViewController子类化为iiFreeman建议并符合委托和数据源协议。然后我在viewDidLoad中设置控制器,并实现了委托和数据源方法。我添加了一个属性存储库,其中包含一个故事板标识符数组,以及一个用于跟踪该数组当前索引的标识符。我还添加了一个辅助方法,在给定索引的情况下返回正确的视图控制器。我的其他tableView控制器子类中不需要任何内容​​,因为我的页面视图控制器正在处理所有内容。我意识到的一件事是,由于我的tableViewController嵌入在导航控制器中,我的页面视图控制器实际上需要显示导航控制器,而不是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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

self.index = self.index + 1

在通话前后发现:

self.index = index + 1

调用当前的ViewController索引。