9

popUpStatusItemMenu を使用して NSStatusItem から NSMenu が飛び出しています。これらの NSMenuItem は一連の異なるリンクを示しており、それぞれが setAction: でターゲットの openLink: メソッドに接続されています。この配置は長い間うまく機能しています。ユーザーがメニューからリンクを選択すると、openLink: メソッドがそれを処理します。

残念ながら、私は最近、NSMenuItem の setView: メソッドを使用して、より洗練されたインターフェースを提供する実験を行うことにしました。基本的に、タイトルの設定をやめ、NSMenuItem を作成し、setView: を使用してカスタム ビューを表示しました。これは完全に機能し、メニュー項目は見栄えがよく、カスタム ビューが表示されます。

ただし、ユーザーがメニュー項目を選択してマウスを放すと、アクションは機能しなくなります (つまり、openLink: は呼び出されません)。setView: 呼び出しを単純にコメントアウトすると、アクションが再び機能します (もちろん、メニュー項目は空白ですが、アクションは適切に実行されます)。私の最初の質問は、ビューを設定すると NSMenuItem のアクションが中断される理由です。

問題ありません。カスタム ビューで mouseUp イベントを検出し、そこからアクション メソッドを呼び出すことで修正できると思いました。このメソッドをカスタム ビューに追加しました。

- (void)mouseUp:(NSEvent *)theEvent {
  NSLog(@"in mouseUp");
  }

ダイスなし!このメソッドは呼び出されません。

ただし、トラッキング rect を設定して mouseEntered: イベントを受け取ることはできます。次のように、mouseEntered ルーチンにいくつかのテストを入れました。

if ([[self window] ignoresMouseEvents]) {  NSLog(@"ignoring mouse events");  }
else {  NSLog(@"not ignoring mouse events");  }
if ([[self window] canBecomeKeyWindow]) {  dNSLog((@"canBecomeKeyWindow"));  }
else {  NSLog(@"not canBecomeKeyWindow");  }
if ([[self window] isKeyWindow]) {  dNSLog((@"isKeyWindow"));  }
else {  NSLog(@"not isKeyWindow");  }

そして、以下の回答を得ました。

not ignoring mouse events
canBecomeKeyWindow
not isKeyWindow

これが問題ですか?「isKeyWindow ではない」? Apple のドキュメントには、「ユーザーがキー ウィンドウにないビューをクリックすると、デフォルトでウィンドウが前面に表示されてキーになりますが、マウス イベントはディスパッチされません」と記載されているため、おそらくこれは適切ではありません。しかし、これらのイベントを検出する方法が必要です。どうやって?

追加:

[[self window] makeKeyWindow];

canBecomeKeyWindow が YES であるにもかかわらず、効果はありません。

4

7 に答える 7

15

このメソッドをカスタム NSView に追加すると、マウス イベントで正常に動作します。

- (void)mouseUp:(NSEvent*) event {
    NSMenuItem* mitem = [self enclosingMenuItem];
    NSMenu* m = [mitem menu];
    [m cancelTracking];
    [m performActionForItemAtIndex: [m indexOfItem: mitem]];
}

しかし、キー処理に問題があります。この問題を解決した場合は、私の質問に行って、少し助けてください。

于 2010-08-07T08:45:54.620 に答える
10

これをカスタム ビューに追加すれば問題ありません。

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
    return YES;
}
于 2010-02-09T19:57:25.650 に答える
9

このメソッドをカスタム ビューに追加したところ、すべてが美しく機能するようになりました。

- (void)viewDidMoveToWindow {
    [[self window] becomeKeyWindow];
}

お役に立てれば!

于 2010-03-13T05:56:57.377 に答える
3

このバージョンを更新しましたSwiftUI Swift 5.3:

final class HostingView<Content: View>: NSHostingView<Content> {
    override func viewDidMoveToWindow() {
        window?.becomeKey()
    }
}

そして、次のように使用します。

let item = NSMenuItem()
let contentView = ContentView()
item.view = HostingView(rootView: contentView)

let menu = NSMenu()
menu.items = [item]
于 2020-09-27T15:05:32.593 に答える
-1

最近、NSStatusItem のカスタム ビューを表示し、クリックすると通常の NSMenu を表示し、ステータス アイコンでのドラッグ アンド ドロップ操作をサポートする必要がありました。

主に、この質問にある 3 つの異なるソースを使用して問題を解決しました。

それが他の人に役立つことを願っています。

于 2013-02-27T11:57:10.993 に答える