【问题标题】:Crash tapping on UILabel - using UIApplication shared keyWindow rootViewController在 UILabel 上点击崩溃 - 使用 UIApplication 共享 keyWindow rootViewController
【发布时间】:2021-07-31 05:49:22
【问题描述】:

我对 Swift 很陌生,我正在为混合应用 (Cordova) 编写一个插件。

我设法让 App rootController 显示一个 ViewController,里面有一个游戏,顶部有一个单独的 UIView 标题,其中包含一个 UILabel 作为后退按钮。

点击后退按钮时,我遇到了崩溃。 我做错了什么?

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!")
    }
}

崩溃前的错误日志:

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

注意:我使用UIApplication.shared.keyWindow,因为它是一个混合应用程序 (Cordova),我正在编写一个插件,允许一些 Javascript 代码使用 Apple 按需资源启动一个 html5 游戏。

一切正常,除了返回主页按钮...

【问题讨论】:

    标签: ios swift objective-c xcode hybrid-mobile-app


    【解决方案1】:

    Target 是应将action 发送到的对象。您需要将handleTap 移动到您的FwViewController 或将目标替换为self,如下所示:

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

    也总是更喜欢#selector 而不是Selector,因为如果你使用了错误的选择器,它会给你一个错误。

    【讨论】:

    • 我无法将 FwViewController 更改为第三方固件。使用 self 和 #selector 有效,谢谢!
    • 其实crash已经解决了但是还是没有打印出log。只有当我注释掉currentWindow?.rootViewController?.present(gameController, .. 时才会这样做。一旦我把它带回来,点击后退按钮就不会再打印出日志了.. :(
    • 解决了将子视图添加到gameController 而不是currentWindow。谢谢
    【解决方案2】:

    崩溃表明MainViewController 没有名称为handleTap 的方法

    似乎currentWindow?.rootViewControllerMainViewController 并且handleTap 函数在MyIntegration 类中。

    因此,在这种情况下,传入self 作为目标或在MainViewController 内实现handleTap

    【讨论】:

    • 其实crash已经解决了但是还是没有打印出log。只有当我注释掉currentWindow?.rootViewController?.present(gameController, .. 时才会这样做。一旦我把它带回来,点击后退按钮就不会再打印出日志了.. :(
    • 不,现在没有崩溃。但是永远不会打印日志。仅当我不提供游戏控制器时才会打印它..
    • 解决了将子视图添加到gameController 而不是currentWindow。谢谢
    猜你喜欢
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2019-03-08
    相关资源
    最近更新 更多