iOS unrecognized selector sent to instance in Swift

a 夏天 提交于 2019-11-27 04:35:10

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!