[Swift] UIPageViewControllerのself.setViewControllersをしても反映されない時に試すこと
W杯日本対セネガル見ながら書いてます
TLTR
- dataSourceを入れ直す
- setViewControllersのanimatedをfalseにする
PageViewControllerのsetViewControllersが反映されないのは、キャッシュが残ったままなのが主な原因かなと思います
なので...
キャッシュをクリアする
dataSourceを入れ直す
PageViewControllerはページ間の移動をスムーズにするために、前後のViewControllerがキャッシュされています
ここで例えば、TabBarControllerで2つタブがあるアプリがあって、
タブ1にPageViewController、タブ2に別のViewControllerだとします
タブ1のPageViewControllerは下の感じ
import UIKit
class PageViewController: UIPageViewController {
override func viewDidLoad() {
// dataSourceの実装をこのクラスに任せる
self.dataSource = self
// storybordのStorybord IDからインスタンス化
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
// そのViewControllerをPageViewControllerに表示する
self.setViewControllers([timelineViewController], direction: .forward, animated: true, completion: nil)
}
override func viewWillAppear() {
// 表示されるViewControllerをリセットする
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.setViewControllers([timelineViewController], direction: .forward, animated: true, completion: nil)
}
}
extension PageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
return timelineViewController
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
return timelineViewController
}
}
このようなアプリでタブ1->タブ2->タブ1という感じでViewControllerを切り替えると、
まずタブ1のPageViewControllerで表示中のViewControllerの前後のViewControllerがキャッシュさるので、タブ2からタブ1に戻ってきたときにviewWillAppearで表示するViewControllerをリセットしようとしても、キャッシュされている前後のViewControllerが左右にフリックすると表示されて、うまくリセットできないことがあります
なので、PageViewControllerないのViewControllerをリセットしたいときはキャッシュもクリアにする必要があります
そのときに使えるのが一度self.dataSourceを入れ直すという技です
import UIKit
class PageViewController: UIPageViewController {
override func viewDidLoad() {
// 同じ
}
override func viewWillAppear() {
// 表示されるViewControllerをリセットする
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.setViewControllers([timelineViewController], direction: .forward, animated: true, completion: nil)
// dataSourceを入れ直す
self.dataSource = nil
self.dataSource = self
}
}
これでキャッシュもクリアされて、意図したようにしっかりViewControllerたちがリセットされます
他の方法
setViewControllersのanimatedをfalseにすると、dataSourceを入れ直さなくてもしっかりリセットされます
import UIKit
class PageViewController: UIPageViewController {
override func viewDidLoad() {
// dataSourceの実装をこのクラスに任せる
self.dataSource = self
// 関数にまとめた
self.setPage()
}
override func viewWillAppear() {
self.setPage()
}
func setPage() {
let timelineViewController = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController
// animatedをfalseにする
self.setViewControllers([timelineViewController], direction: .forward, animated: false, completion: nil)
}
}
これはまだ推測なのですが、trueではキャッシュをクリアしないといけなくて、falseはそうではないことから、
animatedをfalseにすることで、ページ移動のアニメーションがなくなり、
ページ間のフリックが軽くなって、キャッシュする必要がなくなるので、同時にキャッシュをクリアする必要もなくなるのかな~
なんて思ってます
以上
日本がんば
Twitter: https://twitter.com/_tomocy
Author And Source
この問題について([Swift] UIPageViewControllerのself.setViewControllersをしても反映されない時に試すこと), 我々は、より多くの情報をここで見つけました https://qiita.com/tomocy/items/02cf9d63c957f1c8a9fd著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .