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

Posted

技术标签:

【中文标题】Swift 4 UIPageViewController 未显示正确的视图(按顺序在数组中定义【英文标题】:Swift 4 UIPageViewController not showing the correct views (as defined in an array in sequence 【发布时间】:2018-09-20 16:58:17 【问题描述】:

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

我正在使用 2 种视图控制器类型。一个有文章的文本块,另一个没有。

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

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

奖金: 我的下一步是弄清楚如何让视图显示所选的引用/作者/文章。我也非常感谢任何提示,因为这对我来说都是新的。谢谢!

这是我的代码

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



【问题讨论】:

【参考方案1】:

欢迎来到!

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

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 的“定制”控制器,其中大部分都非常糟糕且难以定制,属于以下类别:UIPageViewControllerUITableViewController &UISplitViewController。在我看来,Apple 应该在这些控制器的原型设计方面做得更好,以帮助开发人员更多,但最终这只是我的意见

【讨论】:

对您的代码有一个小的调整。为了发送数据,我必须使 TheController 实例可选。 code theController?.page = theIndex theController?.someData = thePack[theIndex].theQuote code 除此之外,代码运行良好。非常感谢您的帮助! 这绝对有帮助。谢谢!

以上是关于Swift 4 UIPageViewController 未显示正确的视图(按顺序在数组中定义的主要内容,如果未能解决你的问题,请参考以下文章

UIPageViewController 手势覆盖我的 UITableView

swift swift_optional4.swift

swift 如何将Swift 3内置的cocoapod更新为Swift 4

swift Swift 4.2枚举示例

swift Swift 4.1枚举示例

swift Swift - CloudKit订阅 - 4