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" 控制器,其中大部分都非常糟糕且难以定制,在这一类中有以下几种:UIPageViewController
、UITableViewController
& UISplitViewController
。在我看来,Apple 应该在这些控制器的原型设计方面做得更好,以帮助开发人员更多,但最终这只是我的意见
我正在尝试构建一个小型报价应用程序。引号位于对象数组中。有些人有一篇文章提供了有关报价的更多信息。
我正在使用 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" 控制器,其中大部分都非常糟糕且难以定制,在这一类中有以下几种:UIPageViewController
、UITableViewController
& UISplitViewController
。在我看来,Apple 应该在这些控制器的原型设计方面做得更好,以帮助开发人员更多,但最终这只是我的意见