假设我有一个firstViewController和一个secondViewController。第一个包含firstButton,第二个包含secondButton。这就是我想要做的事情:当用户点击secondButton时,一些firstButton的属性会发生变化。
不幸的是,当我在secondViewController中创建firstViewController的实例然后尝试访问firstButton时,我收到错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
所以,从技术上讲,我正在尝试按如下方式执行此操作:
var ins = firstViewController()
@IBAction func secondButtonisPressed(){
ins.firstButton.alpha = 0
}
实施该方法的正确方法是什么?
提前致谢。
答案 0 :(得分:2)
您的问题是IBOutlets
的{{1}}仅在firstViewController
!= nil
方法被调用后才可用(viewDidLoad()
)。
换句话说,您必须展示视图,然后才能对firstViewController
进行任何更改。
如何解决这个问题?
将变量添加到UIViewController IBOutlet
中,作为您的标志。
例如:FirstViewController
var hideFirstButton = false
或viewDidLoad
方法viewWillAppear
检查FirstViewController
的值并隐藏或显示你的hideFirstButton
。
然后,在您提交firstButton
之前,将FirstViewController
的值更改为您的应用程序运行正常所需的值。
<强>更新强>:
使用 Storyboard 的其他解决方法是(这种方法不方便在hideFirstButton
()之后调用完成处理程序,因此该按钮可见一秒):
viewWillAppear
答案 1 :(得分:2)
您可以尝试使用委托来执行此操作,类似于Apple在其现有框架中执行此操作的方式。有关示例,请查看使用UITableView对象时使用UITableViewDelegate的方式。
如果您想使用委派来告诉secondViewController
使用委派对firstButton
进行了压制,您可以按以下方式执行:
第1步: 创建包含按钮按下事件的方法的协议。
protocol buttonPressDelegate {
func buttonPressed() -> Void
}
第2步:
在firstViewController
中,声明您有一个类型为buttonPressProtocol
的对象的实例。
var buttonPressDelegateObj: buttonPressDelegate?
第3步:
在firstViewController
中,初始化buttonPressDelegateObj
以包含对secondViewController实例的引用。如果您愿意,可以创建一个方法来设置buttonPressDelegateObj
中包含的引用,或者在viewDidLoad
中执行firstViewController
等等。
buttonPressDelegateObj = secondViewControllerObj
第4步:
在secondViewController
中,声明您采用buttonPressDelegate
协议。
class secondViewController: UIViewController, buttonPressDelegate {
第5步:
在secondViewController
中,通过添加具有所需实现的函数来实现协议方法buttonPressed()
。这是一个例子:
func buttonPressed() {
secondButton.alpha = 0
}
第6步:
在firstViewController
按钮上创建一个@IBAction,这样当按下按钮时,它会调用buttonPressDelegateObj.buttonPressed()
并且您可以回复该事件
@IBAction func firstButtonPressed() {
if (buttonPressDelegateObj != nil) {
buttonPressDelegateObj.buttonPressed()
}
else {
print("You forgot to set your reference in buttonPressDelegateObj to contain an instance of secondViewController!")
}
}
注意:这只是您可以这样做的一种方式。要告诉firstViewController
secondButton
已被按下(转到其他方向),让firstViewController
实施协议buttonPressDelegate
,让secondViewController
包含对{{1}的引用}}作为firstViewController
类型的实例,并在buttonPressDelegate?
中创建一个@IBAction
,当按下secondViewController
时会触发调用您的secondButton
方法。
注意:Android世界中采用了类似的模式,以便buttonPressDelegate
与Fragment
进行通信,您可以阅读有关here的更多信息