我已经在这个类别中看到了很多问题,但是它们似乎都是以相同的方式回答的,这只是在视图控制器之间传递数据,这不是我想要的。
我有一个VC1,其中存储了数据,在特定情况下,用户需要VC2中的全部信息。我需要将该信息传递回VC1,称为数据“ info”
我希望使用的代码是这样的。我访问VC堆栈,并将变量分配给可选的“ info”变量(在编译时,堆栈不知道VC类型是堆栈中的哪种类型。
let nav = self.navigationController
let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1]
****//code that isn't working
nextView.info = self.info => Value of type 'UIViewController?' has no member 'info'
****//This works fine
nav?.popViewController(animated: true)
答案 0 :(得分:2)
您需要投射
if let let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1] as? VCName {
nextView.info = self.info
}
答案 1 :(得分:2)
假设您在导航堆栈中,并且位于您下方的视图控制器是您需要与之交谈的视图控制器,这是脆弱的。
我的猜测是以前的视图控制器推动了您的工作,并为您提供了您正在编辑的数据。
最好在两个视图控制器之间建立一个委托协议,并在推送之前让自己成为新的视图控制器的委托。然后它将只向其委托发送一条消息以将数据传回。
答案 2 :(得分:2)
nextView
被认为是其超类UIViewController
,因为viewControllers
中的数组UINavigationController
的定义如下([UIViewController]
)。
如果VC1的类型为FirstVC
(UIViewController
的子类),则应将其转换为它的实际类,以便“看到”您的其他属性。下一个视图控制器也是如此。那么,如果执行此操作会发生什么呢?
let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1] as? SecondVC
当然,假设您的nextView
属于SecondVC
类。请记住,面向对象编程具有多态性,其中所有视图控制器都是UIViewController
的后代,因此,它们通常 是UIViewController
这些情况就会发生。
无论如何,正确的方法是定义协议,使FirstVC
符合协议,将第一个视图控制器作为参数传递给SecondVC
,然后在第二个视图控制器中调用选择选项时,将协议方法返回到第一个视图控制器。像这样:
protocol PassDataBackProtocol {
var result: String
}
class FirstVC: UIViewController, PassDataBackProtocol {
var result: String = "" {
didSet {
// Update your view
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let secondVC = segue.destination as? SecondVC {
secondVC.firstVC = self
}
}
}
class SecondVC: UIViewController {
weak var firstVC: PassDataBackProtocol?
func didChangeValue(newValue: String) {
firstVC?.result = newValue
navigationController?.popViewController(animated: true)
}
}
如果您使用pushViewController(_:animated:)
而不是segues,请在进行推送之前设置firstVC
。
编辑:我向后指针添加了weak
属性,因为避免保留子弹很重要。