19

セットをメニューにNSStatusBarしたシンプルなものを作りました。NSMenuまた、このメニューにいくつか追加しましたNSMenuItems。これは正常に機能します(セレクターと強調表示を含む)が、カスタムビュー(setView :)を追加するとすぐに、強調表示は発生しません。

CustomMenuItem *menuItem = [[CustomMenuItem alloc] initWithTitle:@"" action:@selector(openPreferences:) keyEquivalent:@""];
[menuItem foo];
[menuItem setTarget:self];
[statusMenu insertItem:menuItem atIndex:0];
[menuItem release];

そして私のfooメソッドは次のとおりです。

- (void)foo {
  NSView *view = [[NSView alloc] initWithFrame:CGRectMake(5, 10, 100, 20)];
  [self setView:view];
}

setViewメソッドを削除すると、強調表示されます。

検索して検索しましたが、これを実装/有効化する方法が見つかりません。

編集

NSViewサブクラスのこの質問のコードに従ってハイライトを実装しました。

NSMenuItemのビュー(NSViewサブクラスのインスタンス)がホバー時に強調表示されない

#define menuItem ([self enclosingMenuItem])

- (void) drawRect: (NSRect) rect {
    BOOL isHighlighted = [menuItem isHighlighted];
    if (isHighlighted) {
        [[NSColor selectedMenuItemColor] set];
        [NSBezierPath fillRect:rect];
    } else {
        [super drawRect: rect];
    }
}
4

4 に答える 4

10

これは、上記のやや長めのバージョンです。私にとってはうまくいきました。(backgroundColor は ivar です。)

- (void)drawRect:(NSRect)rect
{
    if ([[self enclosingMenuItem] isHighlighted]) {
        [[NSColor selectedMenuItemColor] set];
    } else if (backgroundColour) {
        [backgroundColour set];
    }
    NSRectFill(rect);
}
于 2012-01-22T15:41:13.770 に答える
8

2019 年の更新:

class CustomMenuItemView: NSView {
    private var effectView: NSVisualEffectView

    override init(frame: NSRect) {
        effectView = NSVisualEffectView()
        effectView.state = .active
        effectView.material = .selection
        effectView.isEmphasized = true
        effectView.blendingMode = .behindWindow

        super.init(frame: frame)
        addSubview(effectView)
        effectView.frame = bounds
    }

    required init?(coder decoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ dirtyRect: NSRect) {
        effectView.isHidden = !(enclosingMenuItem?.isHighlighted ?? false)
    }
}

それらのいずれかを に設定しますmenuItem.view

(クレジットは、これを理解するのを手伝ってくれ、ほとんどそのコードをそのまま私に送ってくれた Sam Soffes のものです。)

于 2019-05-22T03:43:17.320 に答える
6

ビューをメニュー項目に追加する場合、そのビューはハイライト自体を描画する必要があります。残念ながら、無料では入手できません。メニュープログラミングトピックから:

ビューを持つメニュー項目は、そのタイトル、状態、フォント、またはその他の標準的な描画属性を描画せず、描画の責任を完全にビューに割り当てます。

于 2011-05-19T06:00:36.697 に答える
3

はい、前述のとおり、自分で描く必要があります。AppKit の NSDrawThreePartImage(…) を使用して描画し、ユーザーのコントロールの外観 (青またはグラファイト) を使用するためのチェックも含めます。画像を取得するために、スクリーンショットから取得しました (誰かがより良い方法を知っている場合は、コメントを追加してください) .) これが私の MenuItemView の drawRect の一部です:

    // draw the highlight gradient
if ([[self menuItem] isHighlighted]) {

    NSInteger tint = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleAquaColorVariant"];
    NSImage *image = (AppleAquaColorGraphite == tint) ? menuItemFillGray : menuItemFillBlue;

    NSDrawThreePartImage(dirtyRect, nil, image, nil, NO,
        NSCompositeSourceOver, 1.0, [self isFlipped]);
}
else if ([self backgroundColor]) {

    [[self backgroundColor] set];
    NSRectFill(dirtyRect);
}

編集

これらを定義する必要があります:

enum AppleAquaColorVariant {
    AppleAquaColorBlue = 1,
    AppleAquaColorGraphite = 6,
};

これらは、システム環境設定の 2 つの外観オプションに対応しています。また、menuItemFillGray と menuItemFillBlue は、標準のメニュー項目塗りつぶしグラデーションの単なる NSImage です。

于 2011-05-20T10:29:43.047 に答える