问题
I am having problems with trying to get a UIButton to work when the user presses it. I keep getting an error saying: unrecognised selector sent to instance
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: "buttonClick", forControlEvents: UIControlEvents.TouchUpInside)
button.setTitle("Print", forState: UIControlState.Normal)
button.font = UIFont(name: "Avenir Next", size: 14)
button.backgroundColor = UIColor.lightGrayColor()
self.view.addSubview(button)
}
func buttonClick(Sender: UIButton!)
{
myLabelInfo.text = "Hello"
}
For a Swift method such as func buttonClick(Sender: UIButton)
what is the correct string to pass to addTarget
method for the selector? Is it "buttonClick", "buttonClick:", "buttonClickSender:" or something else?
回答1:
You're using an invalid method signature for the action. You're supplying buttonClick
, but the method has an argument, so the signature should be buttonClick:
button.addTarget(self, action: "buttonClick:", forControlEvents: UIControlEvents.TouchUpInside)
For more information about how to format your selectors, you can refer to the accepted answer in the post linked below. The code used in this post may be Objective-C, but all its lessons can be applied here as well.
Creating a selector from a method name with parameters
And as a side note, this code would also be valid if you used Selector("buttonClicked:")
as the action, but you don't have to because string literals can be implicitly cast to the Selector type.
Quoting from Using Swift with Cocoa and Objective-C
An Objective-C selector is a type that refers to the name of an Objective-C method. In Swift, Objective-C selectors are represented by the Selector structure. You can construct a selector with a string literal, such as let mySelector: Selector = "tappedButton:". Because string literals can be automatically converted to selectors, you can pass a string literal to any method that accepts a selector.
回答2:
Swift < 2.2
In Swift < 2.2 the selector method cannot be private
(unrecognized selector error).
Prefered (by Apple) notation is the string "methodWithParam:"
notation.
Troubleshooting: if you have troubles with NSTimer
selector, maybe your class should be a subclass of NSObject
.
Swift >= 2.2
Use the #selector
notation. Read more here: https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md
For private methods you can use the @objc
method modifier, like this: @objc private func timerTick(timer: NSTimer)
.
No need for subclassing NSObject
anymore!
回答3:
The notation for Swift > 2.2 would be:
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(YourClass.yourMethod(_:)))
Worked for me so far (Xcode 7.3)
回答4:
You need to pass it an actual Selector
. Try using this line instead:
button.addTarget(self, action: Selector("buttonClick:"), forControlEvents: UIControlEvents.TouchUpInside)
You also need the :
at the end of the selector name because you have 1 argument. This is the same as typical Obj-C selector naming.
回答5:
You have missed the colon while specifying selector.so the line should be
button.addTarget(self, action: Selector("buttonClick:"), forControlEvents: UIControlEvents.TouchUpInside)
回答6:
I had the same problem - the solution ended up being prefixing the method I wanted the button to execute on click with @objc
, to expose it in the Objective-C header file and thereby the Objective-C runtime.
Like:
@objc func buttonClick(Sender: UIButton!)
{
myLabelInfo.text = "Hello"
}
来源:https://stackoverflow.com/questions/24153058/ios-unrecognized-selector-sent-to-instance-in-swift