LoginSignup
6
7

More than 5 years have passed since last update.

NSTrackingAreaの初期化

Last updated at Posted at 2015-11-22

When you create an NSTrackingArea object you must specify one or more options

NSTrackingAreaを初期化するときは、NSTrackingAreaOptionsを1つ以上渡す必要がありますが、このパラメータに制限があるようで、動かすのにちょっと苦労しました。Appleのリファレンスにもこの制限については記述が一切ありません。エラーメッセージでググってもあまり情報がなかったため、ここは一肌脱いでまとめようと思いました。

NSTrackingAreaOptionsは下記の通り10種類定義されています。ドキュメントから抜粋しました。

struct NSTrackingAreaOptions : OptionSetType {
    init(rawValue rawValue: UInt)
    static var MouseEnteredAndExited: NSTrackingAreaOptions { get }
    static var MouseMoved: NSTrackingAreaOptions { get }
    static var CursorUpdate: NSTrackingAreaOptions { get }
    static var ActiveWhenFirstResponder: NSTrackingAreaOptions { get }
    static var ActiveInKeyWindow: NSTrackingAreaOptions { get }
    static var ActiveInActiveApp: NSTrackingAreaOptions { get }
    static var ActiveAlways: NSTrackingAreaOptions { get }
    static var AssumeInside: NSTrackingAreaOptions { get }
    static var InVisibleRect: NSTrackingAreaOptions { get }
    static var EnabledDuringMouseDrag: NSTrackingAreaOptions { get }
}

これだけだとなにもわからないのですが、ソースコードのコメントから情報を得ることができました。(XcodeでNSTrackingAreaOptionsと書いて、command + click で飛んだ定義です。) 注意深くみてみると、Type of tracking area, When tracking area is active, Behavior of tracking area の3種類に分類され、最初の2種類は必須、最後の1種類はoptionalであることがなんとなくわかります。AppleのSDK全般に言えることですが、いろんなところにドキュメントが散乱していて困りますね。ちなみにこの制約を守らないと、ランタイムでクラッシュします。

まとめるとこんな感じのルールになっています。

Type of tracking area (どれか1つ以上必須)

  • MouseEnteredAndExited
  • MouseMoved
  • CursorUpdate

When tracking area is active (どれか1つ以上必須)

  • ActiveWhenFirstResponder
  • ActiveInKeyWindow
  • ActiveInActiveApp
  • ActiveAlways

Behavior of tracking area (optional)

  • AssumeInside
  • InVisibleRect
  • EnabledDuringMouseDrag

エラーメッセージ

ググラビリティ向上のため、エラーになったときのメッセージと対応方法を残しておきます。

trackingArea options 0x20 do not specify when the tracking area is active

When~ が含まれてないよと言っています。
.ActiveWhenFirstResponder,.ActiveInKeyWindow,.ActiveInActiveApp,.ActiveAlwaysのどれか1つ以上を指定してあげましょう。

このエラーになる例

        let options:NSTrackingAreaOptions = [. MouseEnteredAndExited]
        trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil)

trackingArea options 0x20 do not include a type

Type~ が含まれてないよと言ってます。
.MouseEnteredAndExited,.MouseMoved,.CursorUpdate のどれか1つ以上を指定してあげましょう。

このエラーになる例

        let options:NSTrackingAreaOptions = [.ActiveInKeyWindow]
        trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil)

NSTrackingAreaをNSViewに適用する

=== ここから追記しました ===
NSView.trackinAreasはread-onlyです。
実際にNSViewに適用するには下記のようにします。

    override func awakeFromNib() {
        super.awakeFromNib()
        configure()
    }

    func configure() {
        let options:NSTrackingAreaOptions = [
            .MouseEnteredAndExited,
            .MouseMoved,
            .CursorUpdate,
            .ActiveAlways
        ]
        let trackingArea = NSTrackingArea(rect: bounds, options: options, owner: self, userInfo: nil)
        addTrackingArea(trackingArea)
    }

public var trackingAreas: [NSTrackingArea] { get } をOverrideする方法では、mouseEntered: mouseExited: が呼ばれるようになりませんでした。

参考

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7