Swift 2 unrecognized selector in tapgesture

后端 未结 1 1275
长发绾君心
长发绾君心 2021-01-27 10:14

I recently started to update my app to Swift 2.0, but I\'ve run into a problem that has a hundred different answers on SO, none of which seemed to be related to my problem.

1条回答
  •  梦毁少年i
    2021-01-27 10:57

    The issue may be that UIKit does not know how to call a selector that throws, at least in this context.

    Remember that UIKit will be calling this function in response to a tap action. It is not accustomed to calling a function that throws; obviously the throw must alter the method's call signature as far as the Objective-C runtime is concerned. Beyond that, if your function proFormulaTapGesture did throw an error, what would UIKit do with the error even if it could catch it?

    I'm not sure where you added do/try/catch. But unless it was inside your action function proFormulaTapGesture, I do not see how it could be relevant. I believe that you will need to implement the try/catch error handling inside proFormulaTapGesture, so that it effectively swallows the error, so that proFormulaTapGesture does not throw.

    I just created a quick test project myself and found that a throwing target action gives the same "Unrecognized selector" error you got:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.tapper = NSClickGestureRecognizer(target: self, action: "didClick")
        self.view.addGestureRecognizer(self.tapper!)
    }
    
    func didClick() throws {
        print("did click")
    }
    

    2015-07-27 00:16:43.260 Test1[71047:54227175] -[Test1.ViewController didClick]: unrecognized selector sent to instance 0x6000000c5010

    ...

    I believe you will need to rework your code to handle the error internally in your action function so that it does not throw - something like this:

    func proFormulaTapGesture() {
        print("proFormulaTapGesture")
        selectView(proFormulaView)
        selectedMenuItem = 0
        Formula = 1
        menuTabBarController.selectedIndex = 0
        navigationController?.navigationBar.topItem!.title = "BASIC FORMULA"
        do {
            try (menuTabBarController.viewControllers as! [SuggestionsViewController])[0].loadSuggestions()
        } catch {
            // Handle the error here somehow
        }
    }
    

    If you are unable to handle the error within proFormulaTapGesture, you'll have to be more creative with passing it out of the function (think NSNotification, etc...).


    To be clear, I created a new Single View iOS application in Xcode 7 beta 4, and used this exact code as my ViewController. No other changes. The app compiles and works just fine in the iOS simulator.

    @robertvojta also points out that if didTap below is marked private, @objc is also required to avoid a dynamic dispatch crash.

    import UIKit
    
    class ViewController: UIViewController {
    
        var tapper: UITapGestureRecognizer?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.tapper = UITapGestureRecognizer(target: self, action: "didTap")
            self.view.addGestureRecognizer(self.tapper!)
        }
    
        func didTap() {
            print("did Tap")
        }
    
    }
    

    (Note I also tested on an OS X project, which is the code I used earlier in the answer).

    0 讨论(0)
提交回复
热议问题