UIButton.addTarget无法正常工作。似乎是时间安排?

时间:2018-08-02 16:35:14

标签: ios swift uibutton

我正在创建具有2个子视图的ViewController。一个是用于主视图顶部的导航按钮,另一个是位于(WKWebView)下面的浏览器窗口

在主视图控制器的viewDidLoad函数中,创建并添加这些视图作为子视图。然后,我创建按钮并将其添加到navigationView。我以编程方式设置了所有按钮的约束,以定位它们并手动调整它们的大小。

-编辑-

我注意到在检查层次结构中的按钮时,设置了目标,但操作为null。

Here is an image showing this

但是,当我在添加目标后立即检查断点上的操作时,它确实存在。

This was done on a breakpoint immediately after adding the target


我将目标添加如下

btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)

click事件不会触发。但是,如果我在该行之后放置一个断点,然后在控制台中通过

查看按钮的操作
po btnClose!.allTargets

然后它向我显示目标,然后在继续执行时,该按钮可以正常工作。我认为结果是某种时序问题,但我不确定是什么问题。

我正在使用Swift 4.1。

-编辑-

以下是该按钮中涉及的所有代码:(我删除了所有不相关的webview代码)

public func initialize(){ // called by viewDidLoad
    navigationView = UIView(frame:navigationRect)
    navigationView!.isOpaque = true
    navigationView!.isUserInteractionEnabled = true
    navigationView!.backgroundColor = UIColor(red: 58.0/255.0, green: 60.0/255.0, blue: 67.0/255.0, alpha: 1)
    view.addSubview(navigationView!)
    addNavigationButtons()
}
private func addNavigationButtons(){
    btnClose = UIButton()
    btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)

    btnClose!.frame = btnRect // x:0, y:0, width:50, height:50

    btnClose?.translatesAutoresizingMaskIntoConstraints = false
    btnClose!.setImage(UIImage(named: "navigationClose", in: Bundle(identifier:"myframework"), compatibleWith:nil), for:UIControlState.normal)

    navigationView!.addSubview(btnClose!)

    addButtonConstraints()
}

private func addButtonConstraints(){
    // close
    navigationView!.addConstraint(NSLayoutConstraint(item:navigationView!, attribute: .right, relatedBy: .equal, toItem: btnClose!, attribute: .right, multiplier:1.0, constant:0))
    navigationView!.addConstraint(NSLayoutConstraint(item:navigationView!, attribute: .centerY, relatedBy: .equal, toItem: btnClose!, attribute: .centerY, multiplier:1.0, constant:0))
    btnClose!.addConstraint(NSLayoutConstraint(item:btnClose!, attribute: .width, relatedBy:.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:MRAIDBrowserWindow.btnWidth)) //btnWidth = 50
    btnClose!.addConstraint(NSLayoutConstraint(item:btnClose!, attribute: .height, relatedBy:.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:MRAIDBrowserWindow.btnHeight)) //btnHeight = 50
}

@objc public func onCloseClicked(){ // tried this without @objc
    print("this doesn't work, unless I have a breakpoint stoppage")
}

2 个答案:

答案 0 :(得分:0)

首先,我应该告诉你,我不太擅长以编程方式设置约束,因此,我不能为您提供合理的建议。

这是我所做的,我正在共享您自己的工作代码,仅作一些更改...

  1. 我在按钮上添加了自己的图像名称和backgroundColor,以查看某些组件可能会影响按钮
  2. 我已经删除了在btnClose!上设置的框架,因为我注意到当您告诉容器所有方面的约束时,您不需要告诉框架。

更多信息,下面是我编译检查的代码->您的action方法调用很好

导入UIKit

MyTestActionViewController类:UIViewController {

var navigationView : UIView?
var btnClose : UIButton?

override func viewDidLoad() {
    super.viewDidLoad()

    self.initialize()
}

public func initialize(){ // called by viewDidLoad
    navigationView = UIView(frame:CGRect(x:5, y:55, width:200, height:200))
    navigationView!.isOpaque = true
    navigationView!.isUserInteractionEnabled = true
    navigationView!.backgroundColor = UIColor(red: 58.0/255.0, green: 60.0/255.0, blue: 67.0/255.0, alpha: 1)
    view.addSubview(navigationView!)
    addNavigationButtons()
}
private func addNavigationButtons(){
    btnClose = UIButton()
    btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)

    btnClose?.backgroundColor = UIColor.red
    btnClose?.translatesAutoresizingMaskIntoConstraints = false
    btnClose?.setImage(UIImage(named: "myButtonImage"), for:UIControlState.normal)
    navigationView?.addSubview(btnClose!)

    addButtonConstraints()
}

private func addButtonConstraints(){
    // close
    navigationView!.addConstraint(NSLayoutConstraint(item:navigationView!, attribute: .right, relatedBy: .equal, toItem: btnClose!, attribute: .right, multiplier:1.0, constant:0))
    navigationView!.addConstraint(NSLayoutConstraint(item:navigationView!, attribute: .centerY, relatedBy: .equal, toItem: btnClose!, attribute: .centerY, multiplier:1.0, constant:0))
    btnClose!.addConstraint(NSLayoutConstraint(item:btnClose!, attribute: .width, relatedBy:.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:50)) //btnWidth = 50
    btnClose!.addConstraint(NSLayoutConstraint(item:btnClose!, attribute: .height, relatedBy:.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant:50)) //btnHeight = 50
}

@objc public func onCloseClicked(){ // tried this without @objc
    print("this doesn't work, unless I have a breakpoint stoppage")
}

}

图像显示->您的按钮动作正常

enter image description here

答案 1 :(得分:0)

在方法addNavigationButtons中,将以下行放置

btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)

之后

navigationView!.addSubview(btnClose!)

我认为新版本的swift有一个限制,如果某个按钮不在ui视图层次结构中,而您尝试向其添加目标动作,则该按钮实际上将无法工作。因此,请确保首先将按钮添加到ui视图层次结构中。