问题
I am trying to build a small quotes app. The quotes are in an object array. Some have an article which provides some more info about the quote.
I am using 2 viewcontroller types. One has a text block for the article and the other one doesn't.
the UIPageViewController class is set up to allow the user to swipe through the quotes. This is managed by the object array above. The code goes through the array and then, if there is a string on the .article var in the object, it shows one view. If the string is blank, it shows the other one.
I can get the program to swap views, but the counter is not working correctly. This feels like a simple problem, but I'm not able to figure it out.
Bonus: My next step is to figure out how to have the view show the quote/author/article that is selected. I would also really appreciate any tips on that as well as this is all new to me. Thank you!
Here is my code
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:
welcome to SO!
First of all your approach is kind of right, but the main problem is that those methods from the UIPageViewController are not called as you might expect, the thing is if you gently scroll one view controller (so it will scroll back, not go to the next position) it will call one method probably the one with viewControllerAfter
but it won't call the other one when the view scrolls back, which will mess up your index.
I'm not 100% sure that that's your problem but from the implementation it seems so, What I suggest, is to create a super class for all your view controllers that are displayed in the UIPageViewController
and hold the page index on those. And use the page form the controllers in order to compute your position. Something like this
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
}
}
}
And in the end one small advice from my side, be careful with the "custom" controllers from Apple, most of the are really crapy and hard to customise, in this category are the following: UIPageViewController
, UITableViewController
& UISplitViewController
. In my opinion Apple should do a better job in prototyping these controllers to help the developers more, but in the end that's only my opinion
来源:https://stackoverflow.com/questions/52429936/swift-4-uipageviewcontroller-not-showing-the-correct-views-as-defined-in-an-arr