【发布时间】:2019-12-08 10:23:13
【问题描述】:
我正在尝试使用委托将数据数组传递给前一个视图控制器。我决定使用委托,因为我的放松转场不起作用(更多关于 previous Stack Overflow post 的内容)。我已经创建了代理来执行所有必要的设置步骤。
我尝试了this Stack Overflow question 的一些解决方案,但很多答案都是针对我已经完成的事情。我尝试过的事情:
- 重命名协议。
- 重命名代理。
- 使协议不是
class类型。 - 强制解包委托(这个很有趣 - 它导致我的应用程序崩溃,即使我知道委托存在)。
我在ViewControllerB中创建了协议:
protocol ViewControllerBDelegate: class {
func viewControllerB(_ controller: UIViewController, didSelectArray array: [String])
}
我为具有弱引用循环的委托创建了一个变量:
weak var viewControllerBDelegate: ViewControllerBDelegate?
我还从didSelectRowAt 中的代表那里调用了一个函数:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let strArray = ["Hello", "World"]
viewControllerBDelegate?.viewControllerB(self, didSelectArray: strArray)
}
然后在ViewControllerA:
class ViewControllerA: UIViewController, ViewControllerBDelegate
在 ViewControllerB 委托函数中:
func viewControllerB(_ controller: UIViewController, didSelectArray array: [String]) {
print("An array of strings: \(array)")
controller.dismiss(animated: true, completion: nil)
}
在准备转场功能中:
if let viewControllerB = segue.destination as? ViewControllerB {
viewControllerB.viewControllerBDelegate = self
}
我希望委托打印 ViewControllerB 传递的数组的内容。但它不起作用,而且与我的代码的目标不同,视图控制器并没有像预期的那样关闭。
【问题讨论】:
-
有点建设性的批评?我刚刚评论了你的另一个问题——你使用 Xcode 11 beta 有什么原因吗?你想使用
UIKit,对吗?在 Xcode 10 中,代理和 Storyboard 展开都为我工作。如果您的目标不是UIKit,我不知道(并且可能是错误的)有任何理由不使用 Xcode 10。我觉得你把事情复杂化了。让某些东西在 Xcode 10 和 iOS 12(或更早版本)中运行,然后使用测试版。 -
“强制解包代理......导致我的应用程序崩溃”......好吧,所以你已经缩小到
viewControllerBDelegate显然是nil这一事实。所以问题是为什么。因此,请在您的prepare(for:sender:)中添加一个断点,并确保您到达了该行。如果没有,也许您展示了第二个视图控制器而不是对其执行 segue?也许第二个视图控制器嵌入在导航控制器中?根据提供的信息无法判断,但很可能是这样的。 -
无关的,你打电话给
controller.dismiss(animated: true, completion: nil)。请注意,从技术上讲,应该在呈现的视图控制器上调用dismiss,而不是在呈现的视图控制器上。 “呈现视图控制器负责解除它呈现的视图控制器。如果你在呈现的视图控制器本身上调用此方法,UIKit 会要求呈现视图控制器处理解除。”因此,您可以简化并直接调用dismiss(animated: true),而不是controller.dismiss(animated: true)。(注意,这与手头的问题无关,只是一个 FYI。) -
@dfd 我正在使用 Xcode 11 测试版,因为我想为 iOS 13 做准备。我需要使用 iOS 13 SDK。如果 unwind segues 在那里工作,我可能只需要切换回 Xcode 10。
-
@Rob 我忘了提到 ViewControllerB 以模态方式呈现并嵌入在导航控制器中。当我对 ViewControllerB 执行 segue 时,我忘记包含有关导航控制器的代码。这解决了它,