如何从其他视图控制器访问按钮?

时间:2015-12-01 14:36:52

标签: ios swift uiviewcontroller

假设我有一个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
}

实施该方法的正确方法是什么?

提前致谢。

2 个答案:

答案 0 :(得分:2)

您的问题是IBOutlets的{​​{1}}仅在firstViewController != nil方法被调用后才可用(viewDidLoad())。

换句话说,您必须展示视图,然后才能对firstViewController进行任何更改。

  

如何解决这个问题?

将变量添加到UIViewController IBOutlet中,作为您的标志。

例如:FirstViewController

<{1> var hideFirstButton = falseviewDidLoad方法viewWillAppear检查FirstViewController的值并隐藏显示你的hideFirstButton

然后,在您提交firstButton之前,将FirstViewController的值更改为您的应用程序运行正常所需的值。

  

<强>更新

使用 Storyboard 的其他解决方法是(这种方法不方便在hideFirstButton()之后调用完成处理程序,因此该按钮可见一秒):

viewWillAppear
  

示例: an example at GitHub

答案 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世界中采用了类似的模式,以便buttonPressDelegateFragment进行通信,您可以阅读有关here的更多信息