在不同的滑动视图之间传递 UIPageViewController 中的数据
Pass data in UIPageViewController between different swipe views
我正在开发一个包含 3 个视图的项目,可通过滑动访问这些视图。
以下代码实现了我用来处理滑动动作的 PageViewController:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
lazy var orderedViewControllers : [UIViewController] = {
return [self.newVC(viewController : "ClimaVC"),
self.newVC(viewController : "WeatherVC"),
self.newVC(viewController : "ClosetVC")]
}()
var myViewControllers = [UIViewController]()
var currentIndex : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.dataSource = self
setViewControllers([orderedViewControllers[1]],
direction: .forward, animated: true, completion: nil)
self.delegate = self
}
func newVC(viewController : String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1;
guard previousIndex >= 0 else {
// return orderedViewControllers.last
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
currentIndex = previousIndex
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1;
guard orderedViewControllers.count != nextIndex else {
//return orderedViewControllers.first
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
主视图控制器是 WeatherVC。在此视图中,时间数据被检索并存储在名为 timeOfDay 的整数变量中。
根据 timeOfDay 的值,显示的背景会有所不同。虽然我能够在 WeatherVC 中使用此变量,但我需要将此变量 timeOfDay 传递给其他两个视图控制器 ClimaVC 和 ClosetVC。
我尝试设置委托协议但失败了,使用 UIPageViewControllerDelegate 提供的不同功能进行了探索,但它并没有让我得到任何结果。
非常感谢您对此提供帮助,
非常感谢!
并不复杂,只需在 pageviewcontroller 数据源分配值即可。
import UIKit
class ClimaViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print (timeOfDayClima)
}
}
class WeatherViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
timeOfDayClima += 1
}
}
class ClosetViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print (timeOfDayClima)
}
}
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
lazy var orderedViewControllers : [UIViewController] = {
return [self.newVC(viewController : "ClimaVC"),
self.newVC(viewController : "WeatherVC"),
self.newVC(viewController : "ClosetVC")]
}()
var myViewControllers = [UIViewController]()
var currentIndex : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.dataSource = self
setViewControllers([orderedViewControllers[1]],
direction: .forward, animated: true, completion: nil)
self.delegate = self
}
func newVC(viewController : String) -> UIViewController {
return UIStoryboard(name: "Second", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
//Guard = some kind of if statement.
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1;
guard previousIndex >= 0 else {
// return orderedViewControllers.last
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
currentIndex = previousIndex
if(currentIndex == 0) {
(orderedViewControllers.first as! ClimaViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
//Guard = some kind of if statement.
guard let viewControllerIndex = orderedViewControllers.index(of: viewController)
else {
return nil
}
let nextIndex = viewControllerIndex + 1;
guard orderedViewControllers.count != nextIndex else {
//return orderedViewControllers.first
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
currentIndex = nextIndex
if(currentIndex == orderedViewControllers.count - 1) {
(orderedViewControllers.last as! ClosetViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
}
if(nextIndex == 0) {
let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "ClimaVC") as! ClimaViewController
secondVC.timeOfDayClima = 1
}
return orderedViewControllers[nextIndex]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
也许您也应该尝试解释一下在设置委托协议时失败的原因,因为它看起来很可能是您正在寻找的解决方案。我在这里写了一个协议供参考,但是你必须根据你的需要改变它。
protocol WeatherVCDelegate {
func changedTime(timeOfDay: Int)
}
棘手的部分来了。当你在 WeatherVC 中声明一个委托时,你需要使用委托调用函数将 timeOfDay 中继到其他 weatherVC。这是如何工作的,任何符合委托协议的东西都将被触发以使用该功能。
class WeatherVC {
weak var delegate: WeatherVCDelegate?
func functionName() {
delegate?.changedTime(timeOfDay: value)
}
现在,当您在 PageViewController 中初始化 weatherVC 时,您需要 PageViewController 符合 weatherVC 委托。
In PageViewController...
weatherVC.delegate = self
extension PageViewController: WeatherVCDelegate {
...
}
如果我的回答不够清楚,请阅读更多关于代表的内容
https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef
我正在开发一个包含 3 个视图的项目,可通过滑动访问这些视图。
以下代码实现了我用来处理滑动动作的 PageViewController:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
lazy var orderedViewControllers : [UIViewController] = {
return [self.newVC(viewController : "ClimaVC"),
self.newVC(viewController : "WeatherVC"),
self.newVC(viewController : "ClosetVC")]
}()
var myViewControllers = [UIViewController]()
var currentIndex : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.dataSource = self
setViewControllers([orderedViewControllers[1]],
direction: .forward, animated: true, completion: nil)
self.delegate = self
}
func newVC(viewController : String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1;
guard previousIndex >= 0 else {
// return orderedViewControllers.last
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
currentIndex = previousIndex
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1;
guard orderedViewControllers.count != nextIndex else {
//return orderedViewControllers.first
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
}
主视图控制器是 WeatherVC。在此视图中,时间数据被检索并存储在名为 timeOfDay 的整数变量中。
根据 timeOfDay 的值,显示的背景会有所不同。虽然我能够在 WeatherVC 中使用此变量,但我需要将此变量 timeOfDay 传递给其他两个视图控制器 ClimaVC 和 ClosetVC。
我尝试设置委托协议但失败了,使用 UIPageViewControllerDelegate 提供的不同功能进行了探索,但它并没有让我得到任何结果。
非常感谢您对此提供帮助,
非常感谢!
并不复杂,只需在 pageviewcontroller 数据源分配值即可。
import UIKit
class ClimaViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print (timeOfDayClima)
}
}
class WeatherViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
timeOfDayClima += 1
}
}
class ClosetViewController: UIViewController{
var timeOfDayClima: Int = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print (timeOfDayClima)
}
}
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
lazy var orderedViewControllers : [UIViewController] = {
return [self.newVC(viewController : "ClimaVC"),
self.newVC(viewController : "WeatherVC"),
self.newVC(viewController : "ClosetVC")]
}()
var myViewControllers = [UIViewController]()
var currentIndex : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.dataSource = self
setViewControllers([orderedViewControllers[1]],
direction: .forward, animated: true, completion: nil)
self.delegate = self
}
func newVC(viewController : String) -> UIViewController {
return UIStoryboard(name: "Second", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
//Guard = some kind of if statement.
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1;
guard previousIndex >= 0 else {
// return orderedViewControllers.last
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
currentIndex = previousIndex
if(currentIndex == 0) {
(orderedViewControllers.first as! ClimaViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
//Guard = some kind of if statement.
guard let viewControllerIndex = orderedViewControllers.index(of: viewController)
else {
return nil
}
let nextIndex = viewControllerIndex + 1;
guard orderedViewControllers.count != nextIndex else {
//return orderedViewControllers.first
//Return nil to avoid swiping forever.
return nil
}
guard orderedViewControllers.count > nextIndex else {
return nil
}
currentIndex = nextIndex
if(currentIndex == orderedViewControllers.count - 1) {
(orderedViewControllers.last as! ClosetViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
}
if(nextIndex == 0) {
let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "ClimaVC") as! ClimaViewController
secondVC.timeOfDayClima = 1
}
return orderedViewControllers[nextIndex]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
也许您也应该尝试解释一下在设置委托协议时失败的原因,因为它看起来很可能是您正在寻找的解决方案。我在这里写了一个协议供参考,但是你必须根据你的需要改变它。
protocol WeatherVCDelegate {
func changedTime(timeOfDay: Int)
}
棘手的部分来了。当你在 WeatherVC 中声明一个委托时,你需要使用委托调用函数将 timeOfDay 中继到其他 weatherVC。这是如何工作的,任何符合委托协议的东西都将被触发以使用该功能。
class WeatherVC {
weak var delegate: WeatherVCDelegate?
func functionName() {
delegate?.changedTime(timeOfDay: value)
}
现在,当您在 PageViewController 中初始化 weatherVC 时,您需要 PageViewController 符合 weatherVC 委托。
In PageViewController...
weatherVC.delegate = self
extension PageViewController: WeatherVCDelegate {
...
}
如果我的回答不够清楚,请阅读更多关于代表的内容 https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef