Swift - 在 segue 之后保存 ViewController 设置
Posted
技术标签:
【中文标题】Swift - 在 segue 之后保存 ViewController 设置【英文标题】:Swift - save ViewController set up after segue 【发布时间】:2019-11-08 17:59:16 【问题描述】:目前我必须ViewControllers
。您可以使用show-segues
在ViewControllerA
和ViewControllerB
之间切换。问题是每次我切换回来时,ViewControllers 状态都会被重置。如何保存 ViewController
的设置?
从 A 到 B
@IBAction func editButtonTapped(_ sender: Any)
let imageCollectionView = self.storyboard?.instantiateViewController(withIdentifier: "ImageCollectionVC") as! ImageCollectionViewController
self.navigationController?.pushViewController(imageCollectionView, animated: true)
从 B 到 A
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
tappedImage = images[indexPath.row]
performSegue(withIdentifier: "backToPopUpView", sender: self)
【问题讨论】:
“问题是每次我切换回来时,ViewControllers 状态都会被重置。”那么你实际上并没有切换回来。你能展示一些代码让我们知道你目前在做什么吗? 我编辑了我的问题 查看您的代码,您并没有在视图控制器之间来回移动,而是在每次更改时创建视图控制器的新实例。所以你实际上是在做 A > B > A1 > B1 > A2 > B2 等等,这就是为什么没有保留状态。您需要弹出视图控制器 B 才能返回到 A。顺便说一下,您也没有在 A 到 B 中使用 segue。 Passing Data between View Controllers的可能重复 @flanker 那我该怎么做呢? 【参考方案1】:要在视图控制器之间移动以两种方式传递数据,您需要做一些事情
一致的导航方法:segues 或 push/popping 通过导航控制器或模态 presenting/dismissing,但不是将它们混合用于一个 A - B - A 过渡
允许将数据从子代传回父代的协议/委托。
在下面的示例中,导航是通过导航控制器进行的,并且使用图像作为如何将数据传递回父级的示例。在其他情况下调整它应该是微不足道的。
子类需要与其父类达成一致的接口以允许它进行通信。这是通过协议完成的。在这个例子中,我们为孩子提供了一种将更新后的图像传回给父母的方法:
protocol ClassBDelegate
func childVCDidComplete(with image: UIImage?)
然后在子类中创建一个委托变量,该变量可以指向任何采用协议的类(在这种情况下将是它的父类),然后使用该委托和协议的函数将图像数据传回。一旦数据通过委托传回,视图控制器 B 调用导航控制器的 popViewCntroller
方法来关闭自身并将焦点返回给视图控制器 A
class B: UIViewController
var delegate: ClassBDelegate?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
tappedImage = images[indexPath.row]
delegate?.childVCDidComplete(with: tappedImage)
navigationController?.popViewController(animated: true)
为了使这一切正常工作,需要将子视图控制器的委托设置为指向其父视图控制器 (A),但在此之前,该类需要符合协议:
extension A: ClassBDelegate
func childVCDidComplete( with image: UIImage?)
self.image = image
现在,当实例化子视图控制器时,父母将自己设置为委托,从而完成通信循环。
Class A: UIViewController
var image: UIImage?
@IBAction func editButtonTapped(_ sender: Any)
let imageCollectionView = self.storyboard?.instantiateViewController(withIdentifier: "ImageCollectionVC") as! ImageCollectionViewController
imageCollectionView.delegate = self
self.navigationController?.pushViewController(imageCollectionView, animated: true)
【讨论】:
抱歉,我正在努力在我的代码中实现这一点。我到底要在哪里实现extension
和 protocol
?
我使用A
和B
作为A 和B 视图控制器的简写,所以用各自的类名替换它们。然后,您可以在其自己的文件中或在与视图控制器 B 相同的文件中,在 import 语句和您的类定义之间实现协议。您将视图控制器 A 的扩展放在它的类定义下方 - 在最后一个
之后。在这里解释有关协议/代表的所有内容的范围太广了,但是如果您在 YouTube 上查看 Sean Allen 有一个非常好的视频教程。
我实现了它,但现在如果我点击一个项目没有任何反应
popViewController
即使被调用也不做任何事情,我用print
对其进行了测试
我怀疑您没有完全正确地实现它,或者您没有显示其他代码与它冲突,因为我从工作模型中复制了代码。什么项目什么都不做? popviewcontroller 仅在您最初使用 push(使用导航控制器)呈现视图控制器时才有效,而不是在您以模态方式呈现或使用 segue 时。【参考方案2】:
您创建了新的 ViewControllerA,并且您有以下结果 A -> B -> A。 但这不是真的,你应该解雇 ViewControllerB...
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
tappedImage = images[indexPath.row]
self.dismiss(animated: true, completion: nil)
//performSegue(withIdentifier: "backToPopUpView", sender: self)
【讨论】:
但我正在传递一个UIImage
与那个segue。如果我只是 self.dismiss
那张图片不会通过
您必须通过两种方式传递信息。 1.使用协议 2. 在 ViewControllerB 中,您必须具有“parentVC:ViewControllerA”或“vcA:ViewControllerA”属性...而在 ViewControllerA 中,您必须编写这一行 imageCollectionView.vcA = self。在 ViewControllerB 中你可以通过 self.vcA.image = tappedImage
你能详细说明一下吗?:) 我不能在 ViewControllerA 中写 imageCollectionView.vcA = self
以上是关于Swift - 在 segue 之后保存 ViewController 设置的主要内容,如果未能解决你的问题,请参考以下文章
Swift UI集合视图 - 如何在Cell中显示“segued”用户输入?
Swift,SpriteKit,GameViewController 和 MainViewController 在 GameOver 之后的 Segue