在页面视图控制器内使用导航控制器时重复视图控制器

Duplicate view controllers when using nav controllers inside page view controller

感谢 Using UIPageViewController with swift and multiple view controllers,我将导航控制器嵌入到 UIPageViewController 中,这样我就可以水平滚动浏览它们(如滑动导航)。问题:

当我到达第一个或最后一个导航控制器,然后向相反方向滑动时,第二个-to-first/last 导航控制器将复制。所以我会有 5 个导航控制器。例如:

从 FirstNav 开始,一直向左滑动到 FourthNav。当我从 FourthNav 向右滑动控制器阵列时,顺序将是:ThirdNav、ThirdNav、SecondNav、FirstNav。谁能知道这是怎么回事?

 class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

        var index = 0
        var identifiers: NSArray = ["FirstNav", "SecondNav", "ThirdNav", "FourthNav"]

        override func viewDidLoad() {
            super.viewDidLoad()

            self.dataSource = self
            self.delegate = self

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

        }

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

            if index == 0 {

                return self.storyboard!.instantiateViewControllerWithIdentifier("FirstNav") as! UINavigationController
            }


            if index == 1 {

               return self.storyboard!.instantiateViewControllerWithIdentifier("SecondNav") as! UINavigationController

            }

           if index == 2 {

               return self.storyboard!.instantiateViewControllerWithIdentifier("ThirdNav") as! UINavigationController
           }

           if index == 3 {

               return self.storyboard!.instantiateViewControllerWithIdentifier("FourthNav") 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 0
    }

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


}

问题与您在 pageViewController(_:viewControllerBeforeViewController:)pageViewController(_:viewControllerAfterViewController:) 方法中计算 index 变量有关。为了简化该逻辑和页面视图控制器的整体逻辑,您应该将实现更改为以下内容:

class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    private var pages: [UIViewController]!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.dataSource = self
        self.delegate = self

        self.pages = [
            self.storyboard!.instantiateViewControllerWithIdentifier("FirstNav") as! UINavigationController,
            self.storyboard!.instantiateViewControllerWithIdentifier("SecondNav") as! UINavigationController,
            self.storyboard!.instantiateViewControllerWithIdentifier("ThirdNav") as! UINavigationController,
            self.storyboard!.instantiateViewControllerWithIdentifier("FourthNav") as! UINavigationController
        ]

        let startingViewController = self.pages.first! as UIViewController
        self.setViewControllers([startingViewController], direction: .Forward, animated: false, completion: nil)
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        let index = (self.pages as NSArray).indexOfObject(viewController)

        // if currently displaying last view controller, return nil to indicate that there is no next view controller
        return (index == self.pages.count - 1 ? nil : self.pages[index + 1])
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        let index = (self.pages as NSArray).indexOfObject(viewController)

        // if currently displaying first view controller, return nil to indicate that there is no previous view controller
        return (index == 0 ? nil : self.pages[index - 1])
    }

}

你甚至不需要维护一个 index 实例变量,而且这个实现也没有这样做。但如果你愿意,你可以。该解决方案还为每个 UINavigationController 实例化一个实例,而不是每次用户尝试滚动到不同页面时都实例化一个新实例,这样可以节省内存并在用户在视图控制器之间滚动时保留视图控制器的状态。

请原谅非描述性的 pages 变量名。我不想与 UIPageViewControllerviewControllers 属性.

产生冲突