Swift - 在 UIPageViewController 中的 3 个不同视图控制器之间导航按钮
Swift - Navigate through buttons between 3 different View Controllers in UIPageViewController
所以我一直在尝试 UIPageViewController,其中我有三个不同的视图控制器(3 个不同的 类)
所以我成功了!我可以完美地从 View Controller 滑动到 View Controller!在这三个 类 的 viewDidLoad 中,我分别使它们的 self.view.tag = 0,1,2,所以我知道我当前的视图控制器是哪个。这是我的 RootViewController 的代码:
import UIKit
class ViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
@IBOutlet var bottomView: UIView!
var pageViewController: UIPageViewController!
var currentVCId = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
pageViewController.dataSource = self
pageViewController.delegate = self
let starterVC = viewControllerWith(id: 0)
pageViewController.setViewControllers([starterVC], direction: .forward, animated: false, completion: nil)
pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.addChildViewController(pageViewController)
self.view.addSubview(pageViewController.view)
self.view.bringSubview(toFront: bottomView)
pageViewController.didMove(toParentViewController: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewControllerWith(id: Int) -> UIViewController {
if id == 0 {
return self.storyboard?.instantiateViewController(withIdentifier: "FirstPageContentViewController") as! FirstPageContentViewController
}
else if id == 1 {
return self.storyboard?.instantiateViewController(withIdentifier: "SecondPageContentViewController") as! SecondPageContentViewController
}
else {
return self.storyboard?.instantiateViewController(withIdentifier: "RandomColorViewController") as! RandomColorViewController
}
}
func getViewControllerIdFor(previousViewController: Bool) -> Int? {
if previousViewController == true {
return currentVCId == 0 ? nil : currentVCId - 1
}
return currentVCId == 2 ? nil : currentVCId + 1
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let returnIdValue = getViewControllerIdFor(previousViewController: true) {
return viewControllerWith(id: returnIdValue)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let returnIdValue = getViewControllerIdFor(previousViewController: false) {
return viewControllerWith(id: returnIdValue)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard completed else {
return
}
let viewController = pageViewController.viewControllers![0]
currentVCId = viewController.view.tag
}
@IBAction func goToA(_ sender: UIButton) {
if currentVCId != 0 {
let currentVC = pageViewController.viewControllers?[0]
let previusVC = pageViewController(pageViewController, viewControllerBefore: currentVC!)
pageViewController.setViewControllers([previusVC!], direction: .reverse, animated: true, completion: nil)
currentVCId = 0
}
}
}
事实是,我已经向我的 RootViewController 添加了 2 个按钮,无需滑动即可从 View Controller 切换到 View Controller。因此,假设我已经滑动到第二个 View Controller 并且我想去回到我的第一个,按左键。记住我的第一个 VC 已经加载,所以我可以修改它的内容..
所以现在,如果我按下按钮,它的代码是上面的最后一个方法,它会导航回来,但它会创建所需 VC 的新实例!我想做的是显示我已经加载的 VC,就好像我刷了一样...就像 Snapchat...
知道如何实现吗?
这是来自documentation instantiateViewController(withIdentifier:)
This method creates a new instance of the specified view controller each time you call it.
这就是您获得新实例的原因。我会推荐一种不同的方法。与其让 pageViewController 跟踪 VC 并通过索引和标签盲目访问它们,为什么不将它们作为 属性 存储在根目录中?这将允许您确保 VC 的相同实例,并让您从检查标签(脏)到更易读的东西,例如检查与实际 VC 对象的相等性。
所以我一直在尝试 UIPageViewController,其中我有三个不同的视图控制器(3 个不同的 类)
所以我成功了!我可以完美地从 View Controller 滑动到 View Controller!在这三个 类 的 viewDidLoad 中,我分别使它们的 self.view.tag = 0,1,2,所以我知道我当前的视图控制器是哪个。这是我的 RootViewController 的代码:
import UIKit
class ViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
@IBOutlet var bottomView: UIView!
var pageViewController: UIPageViewController!
var currentVCId = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
pageViewController.dataSource = self
pageViewController.delegate = self
let starterVC = viewControllerWith(id: 0)
pageViewController.setViewControllers([starterVC], direction: .forward, animated: false, completion: nil)
pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.addChildViewController(pageViewController)
self.view.addSubview(pageViewController.view)
self.view.bringSubview(toFront: bottomView)
pageViewController.didMove(toParentViewController: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewControllerWith(id: Int) -> UIViewController {
if id == 0 {
return self.storyboard?.instantiateViewController(withIdentifier: "FirstPageContentViewController") as! FirstPageContentViewController
}
else if id == 1 {
return self.storyboard?.instantiateViewController(withIdentifier: "SecondPageContentViewController") as! SecondPageContentViewController
}
else {
return self.storyboard?.instantiateViewController(withIdentifier: "RandomColorViewController") as! RandomColorViewController
}
}
func getViewControllerIdFor(previousViewController: Bool) -> Int? {
if previousViewController == true {
return currentVCId == 0 ? nil : currentVCId - 1
}
return currentVCId == 2 ? nil : currentVCId + 1
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let returnIdValue = getViewControllerIdFor(previousViewController: true) {
return viewControllerWith(id: returnIdValue)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let returnIdValue = getViewControllerIdFor(previousViewController: false) {
return viewControllerWith(id: returnIdValue)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
guard completed else {
return
}
let viewController = pageViewController.viewControllers![0]
currentVCId = viewController.view.tag
}
@IBAction func goToA(_ sender: UIButton) {
if currentVCId != 0 {
let currentVC = pageViewController.viewControllers?[0]
let previusVC = pageViewController(pageViewController, viewControllerBefore: currentVC!)
pageViewController.setViewControllers([previusVC!], direction: .reverse, animated: true, completion: nil)
currentVCId = 0
}
}
}
事实是,我已经向我的 RootViewController 添加了 2 个按钮,无需滑动即可从 View Controller 切换到 View Controller。因此,假设我已经滑动到第二个 View Controller 并且我想去回到我的第一个,按左键。记住我的第一个 VC 已经加载,所以我可以修改它的内容..
所以现在,如果我按下按钮,它的代码是上面的最后一个方法,它会导航回来,但它会创建所需 VC 的新实例!我想做的是显示我已经加载的 VC,就好像我刷了一样...就像 Snapchat...
知道如何实现吗?
这是来自documentation instantiateViewController(withIdentifier:)
This method creates a new instance of the specified view controller each time you call it.
这就是您获得新实例的原因。我会推荐一种不同的方法。与其让 pageViewController 跟踪 VC 并通过索引和标签盲目访问它们,为什么不将它们作为 属性 存储在根目录中?这将允许您确保 VC 的相同实例,并让您从检查标签(脏)到更易读的东西,例如检查与实际 VC 对象的相等性。