我所面临的问题是理解当我调用prepare(forSegue:)方法时发生了什么。我得到了数据从MainVeiwController传递到SecondViewController的机制。特别是在传递值时,我无法从SecondViewController的MainViewController初始化@IBOUTLET,但可以初始化其他可选属性,如var name:String? of SecondViewController。只是有点好奇而已。
进一步阐述这一问题:
主视图的类:
class MainViewController:UIViewController{
..
..
..
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let yourVC = segue.destinationViewController as? SecondViewController {
// this doesn't throw any error
yourVC.someData = self.someData
// this throws an error
yourVC.textLabel.text = self.someData
}
}
}第二视图的类:
class SecondViewController:UIViewController{
@IBOULET weak var textLabel:UILabel!
var someData:String?
..
..
..
}发布于 2017-08-07 11:59:52
创建UIViewController实例时,它不包含任何视图(除非您自己在初始化器中添加了视图--请不要这样做)。
当viewController第一次出现时,它会检查view是否为nil,如果为零,它将从nib或情节提要加载自己,并将视图注入viewController并为您调用viewDidLoad(_:),因此在prepare(forSegue:)系统中只为您实例化一个viewController (基于segue目标类型),您必须配置它的data,而不是它的视图。如果您想要控制视图,可以调用loadViewIfNeeded(),这将迫使viewController加载它的视图(这是一个反模式,如果这是您唯一的选择,就使用它)。
通常情况下是这样的:
您可以从外部定义一些可设置的变量。例:var someString: String!,它告诉编译器忽略这个值是否为零(或者设置一些默认值,如果您愿意)。在您的viewDidLoad()方法中,将它们分配给您所知道的相关视图。
我们知道,这会破坏OOD,但是当您使用故事板时,这是唯一的选择,因为系统负责实例化和加载/卸载视图/视图控制器。如果您想要干净地编码,可以定义一个viewController并通过nib设置它的视图,并在初始化器中处理所有这些事情。(但是要小心,您必须遵守加载视图、卸载视图或.的系统规则,因为这些任务具有很高的进程和内存消耗,这就是为什么这样定义它们的原因)
发布于 2017-08-07 11:31:48
viewDidLoad in SecondViewController通常被称为 prepare(forSegue:)之后的,因此在prepare(forSegue:)中,SecondViewController的所有IBOutlet都尚未连接,无法访问。
https://stackoverflow.com/questions/45545681
复制相似问题