Swift 4 UIPageViewController 未显示正确的视图(按顺序在数组中定义

Swift 4 UIPageViewController not showing the correct views (as defined in an array in sequence

我正在尝试构建一个小型报价应用程序。引号位于对象数组中。有些人有一篇文章提供了有关报价的更多信息。

我正在使用 2 viewcontroller 种类型。一个有文章的文本块,另一个没有。

UIPageViewController class 设置为允许用户轻扫引号。这是由上面的对象数组管理的。代码遍历数组,然后,如果对象中的 .article var 中有一个字符串,它会显示一个视图。如果字符串为空,则显示另一个。

我可以让程序交换视图,但计数器无法正常工作。这感觉像是一个简单的问题,但我无法弄清楚。

奖金: 我的下一步是弄清楚如何让视图显示所选的 quote/author/article。我也非常感谢有关这方面的任何提示,因为这对我来说都是全新的。谢谢!

这是我的代码

import UIKit

var thePack:[packItem] = [packItem(theQuote: "quote1", author: "", article: "hasarticle3"),packItem(theQuote: "quote2", author: "", article: ""),packItem(theQuote: "quote3", author: "", article: "hasarticle3")]

var packIndex:Int = 0

class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

//set up the array of views to move to. All the different view types should be in here
lazy var subViewControllers:[UIViewController] = {
    return [
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen1") as! ViewController1,
        UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen2") as! ViewController2
    ]
}()
//end

override func viewDidLoad() {
    super.viewDidLoad()
    self.delegate = self
    self.dataSource = self

    //set up the initial viewController
    setViewControllers([subViewControllers[0]], direction: .forward, animated: true, completion: nil)
}


//set up the before view
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

    packIndex -= 1
    if(packIndex <= 0){
        return nil
    }
    else{
        if thePack[packIndex].article != ""{
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen1") as! ViewController1
        }

        else{
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen2") as! ViewController2
        }
    }
}

//set up the after view
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

    packIndex += 1

    if(packIndex >= thePack.count){
        return nil
    }
    else{
        if thePack[packIndex].article != ""{
            return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen1") as! ViewController1
        }

        else{
            return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen2") as! ViewController2
        }
    }
}

//change the transition style so it's not the page curl
required init?(coder: NSCoder) {
    super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}


//MARK UIPageViewController DataSource
func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return subViewControllers.count
}

}

欢迎来到 SO!

首先,您的方法是正确的,但主要问题是 UIPageViewController 中的那些方法没有像您预期的那样被调用,问题是如果您轻轻滚动一个视图控制器(这样它会向后滚动,不会转到下一个位置)它会调用一个方法,可能是带有 viewControllerAfter 的方法,但是当视图向后滚动时它不会调用另一个方法,这会弄乱您的索引。 我不是 100% 确定那是你的问题,但从实现来看似乎是这样,我的建议是为显示在 UIPageViewController 中的所有视图控制器创建一个超级 class 并保持那些的页面索引。并使用控制器的页面来计算您的位置。像这样

class MyPageViewController: UIViewController {
    var page: Int = 0
}

class OneControllerThatWillBeDisplayed: MyPageViewController {
   // do adittional things here
}


class ThePageViewController ...delegates here {

//set up the before view
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    let theController = viewController as! MyPageViewController
    let theIndex = theController.page - 1
    if(theIndex < 0){
        return nil
    }
    else{
        if thePack[theIndex].article != ""{
            let theController =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen1") as? MyPageViewController
            theController.page = theIndex
            return theController
        }

        else{
            let theOtherOne  =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen2") as! MyPageViewController
            theOtherOne.page = theIndex
            return theOtherOne
        }
    }
}

//set up the after view
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

    let theController = viewController as! MyPageViewController
    let theIndex = theController.page + 1
    if(theIndex >= thePack.count){
        return nil
    }
    else{
        if thePack[theIndex].article != ""{
            let theController =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen1") as? MyPageViewController
            theController.page = theIndex
            return theController
        }

        else{
            let theOtherOne  =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "screen2") as! MyPageViewController
            theOtherOne.page = theIndex
            return theOtherOne
        }
    }
}

最后是我的一个小建议,小心使用 Apple 的 "custom" 控制器,其中大部分都非常糟糕且难以定制,在这一类中有以下几种:UIPageViewControllerUITableViewController & UISplitViewController。在我看来,Apple 应该在这些控制器的原型设计方面做得更好,以帮助开发人员更多,但最终这只是我的意见