Gabe
Gabe

Reputation: 6347

Crash tapping on UILabel - using UIApplication shared keyWindow rootViewController

I am fairly new to Swift, I am writing a plugin for a hybrid App (Cordova).

I managed to have the App rootController display a ViewController with a game inside and a separate UIView header at the top that contains a UILabel as a back button.

I am experiencing a crash as soon as I tap on the back button. What am I doing wrong?

import SomeFramework;

@objc (MyIntegration) class MyIntegration : SomeFrameworkDelegate {
    func implementedFunctionForDelegate(_ controller: FwViewController) {
      print("fwViewControllerDidHandleSomeEvent");
    }
    // ...

    @objc(launchGame:)
    func launchGame() {
      // Prep params
      let params = FwLaunchParameters.init()
      params.gameId = gameId
      
      // ViewController init
      let gameController = FwViewController.init(gameLaunchParameters: params)
      gameController.delegate = self
      
      // Display game using rootViewController
      let currentWindow: UIWindow? = UIApplication.shared.keyWindow
      currentWindow?.rootViewController?.present(gameController, animated: true, completion: nil)

      let backHomeHeader = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 80.0))
      let label = UILabel(frame: CGRect(x: 0, y: 28, width: 200, height: 50))
      label.text = "\u{3008} Back Home"
      label.isUserInteractionEnabled = true
      let gestureRecognizer = UITapGestureRecognizer(target: currentWindow?.rootViewController, action: Selector("handleTap"))
      label.addGestureRecognizer(gestureRecognizer)
      
      handleTap() // prints out the log as expected

      // Display header
      currentWindow?.addSubview(backHomeHeader)
      backHomeHeader.addSubview(label)
    }

    @objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
      print("tapped! yay!")
    }
}

Error log right before the crash:

2021-07-31 01:17:24.790750-0400 MyApp[53004:2197131] -[MainViewController handleTap]: unrecognized selector sent to instance 0x7fdb44906490
2021-07-31 01:17:24.842133-0400 MyApp[53004:2197131] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MainViewController handleTap]: unrecognized selector sent to instance 0x7fdb44906490'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff20422fba __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007fff20193ff5 objc_exception_throw + 48

Note: I use UIApplication.shared.keyWindow because it's a hybrid App (Cordova) and I'm writing a plugin that allows some Javascript code to launch an html5 game using Apple On-Demand Resources.

Everything works fine except for the Back Home button...

Upvotes: 0

Views: 375

Answers (2)

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119706

The crash says that the MainViewController has no method with the name handleTap

It seems currentWindow?.rootViewController is MainViewController and the handleTap function is in MyIntegration class.

So pass in self as the target or implement the handleTap inside the MainViewController for this case.

Upvotes: 1

Phil Dukhov
Phil Dukhov

Reputation: 88072

Target is an object to which action should be sent. You need to move handleTap to your FwViewController or to replace target with self, like this:

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))

Also always prefer #selector to Selector because it'll give you an error if you're using a wrong selector.

Upvotes: 2

Related Questions