Swift 4中的选择器实现

时间:2017-11-11 22:20:50

标签: swift nsview

我正在尝试定义NSRect跟踪。在一个新项目中,我只是在ViewController.swift文件中添加了几行:

import Cocoa

class ViewController: NSViewController {
    let tester = Test()
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addTrackingRect(view.bounds, owner: tester, userData: nil, assumeInside: false)
    }
}

class Test: NSObject {
    @objc func mouseEntered(with event: NSEvent) {
        print("mouseEntered")
    }
    @objc func mouseExited(with event: NSEvent) {
        print("mouseExited")
    }
    override func responds(to aSelector: Selector!) -> Bool {
        print("aSelector: -> \(aSelector) -> \(super.responds(to: aSelector))")
        return super.responds(to: aSelector)
    }
}

结果是应用程序崩溃:

  

aSelector: - >可选(mouseEntered :) - >假   2017-11-12 00:18:56.204723 + 0200 test21 [19694:1744132] ***断言失败 - [NSWindow _setTrackingRect:inside:owner:userData:useTrackingNum:install:],/ BuildRoot / Library / Caches / com。 apple.xbs /来源/了AppKit /了AppKit-1561.10.101 / AppKit.subproj / winTrackingAreas.m:408   2017-11-12 00:18:56.207360 + 0200 test21 [19694:1744132] [一般]未被捕获的例外被提出   2017-11-12 00:18:56.207382 + 0200 test21 [19694:1744132] [一般]窗口:跟踪rect的目标不理解-mouseEntered:或-mouseExited消息

所以我的问题是 - 如何定义一个有效的选择器???

1 个答案:

答案 0 :(得分:0)

addTrackingRect(_:owner:userData:assumeInside:)的Swift文档非常具有误导性;它说主人应该回复

  

同时发送mouseEntered(with:)mouseExited(with:)

然而,应该说的是它需要响应选择器mouseEntered:& mouseExited:,因为默认情况下,mouseEntered(with:)等方法的选择器为mouseEnteredWith:,因为参数标签是签名的一部分。

因此,要解决此问题,您可以:

  1. 删除参数标签:

    class Test : NSObject {
      @objc func mouseEntered(_ event: NSEvent) {
        print("mouseEntered")
      }
    
      @objc func mouseExited(_ event: NSEvent) {
        print("mouseExited")
      }
      // ...
    }
  2. 手动定义选择器:

    class Test : NSObject {
      @objc(mouseEntered:) func mouseEntered(with event: NSEvent) {
        print("mouseEntered")
      }
    
      @objc(mouseExited:) func mouseExited(with event: NSEvent) {
        print("mouseExited")
      }
      // ...
    }