I am creating a ViewController with 2 child views. One is for navigation buttons that is on the top of my main view, and a browser window below (WKWebView)
In the main view controller's viewDidLoad function I create and add these views as subviews. I then create and add buttons to the navigationView. I programatically set the constraints of all the buttons to position them and size them manually.
-- Edit --
I noticed that when inspecting the button in the hierarchy, the target is set but the action is null.
However, when I check the actions on a breakpoint immediately after adding the target, it does appear to be there.
This was done on a breakpoint immediately after adding the target
I am adding the target as follows
btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)
The click event does not fire. However if I put a breakpoint after that line, and in the console I look at the actions for the button via
po btnClose!.allTargets
Then it shows me the target, and then when continuing execution the button works fine. I assume there's some sort of timing issue as a result but I'm not sure what the problem is.
I'm using Swift 4.1.
-- Edit --
Here is all the code involved in that button: (I removed all the webview code that isn't relevant)
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")
}
First of all I should have tell you that I am not so good at setting constraints programatically, so I cannot suggest you a reasonable suggestion to that.
Here is what I have done and I am sharing the working code of your own, with a few only changes...
further more you should have a look on to it, down here is he code I have compiled to check -> your actions method calls fine
import UIKit
class 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")
}
}
An image showing -> your button action acting properly
Within method addNavigationButtons
, put the following the line
btnClose!.addTarget(self, action: #selector(onCloseClicked), for:UIControlEvents.touchUpInside)
after
navigationView!.addSubview(btnClose!)
I think there is a restriction with the new version of swift, if a button is not in a ui view hierarchy, and you try to add a targe-action onto it, it won't actually work. So make sure that the button is added into a ui view hierarchy first.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.