Objective c 使用自定义NSView在NSMenuItem上悬停时更改背景色

Objective c 使用自定义NSView在NSMenuItem上悬停时更改背景色,objective-c,macos,cocoa,nsview,nsmenuitem,Objective C,Macos,Cocoa,Nsview,Nsmenuitem,事情是这样的: @interface customView : NSView @end @implementation customView - (id)initWithFrame:(NSRect)frame { NSRect theRect = NSMakeRect(0, 0, 200, 30); self = [super initWithFrame:theRect]; if (self) { NSTrackingArea * tracking

事情是这样的:

@interface customView : NSView  
@end  
@implementation customView

- (id)initWithFrame:(NSRect)frame
{

    NSRect theRect = NSMakeRect(0, 0, 200, 30);
    self = [super initWithFrame:theRect];
    if (self) {
    NSTrackingArea *   trackingArea = [[NSTrackingArea alloc] initWithRect:theRect
                                                    options: (NSTrackingMouseEnteredAndExited  | NSTrackingActiveInKeyWindow  |NSTrackingActiveAlways)
                                                      owner:self userInfo:nil];
        [self addTrackingArea:trackingArea];
    }

    return self;
}

#define menuItem ([self enclosingMenuItem])

- (void) drawRect: (NSRect) rect {


    BOOL isHighlighted = [menuItem isHighlighted];
    if (isHighlighted) {
        //this nslog never happens
        NSLog(@"it's highlighted");
}



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


    NSLog(@"you clicked the %ld item",[m indexOfItem: mitem]);
}
@end
我创建了一个自定义
NSMenuItem
,其中包含一个自定义
NSView

一切正常,只是我无法突出显示
NSMenuItem
(=更改鼠标上方的背景色)

我试图在
drawRect
方法中实现这一点,如这里发布的其他答案所示

我做错了什么


查看
NSView
子类:

@interface customView : NSView  
@end  
@implementation customView

- (id)initWithFrame:(NSRect)frame
{

    NSRect theRect = NSMakeRect(0, 0, 200, 30);
    self = [super initWithFrame:theRect];
    if (self) {
    NSTrackingArea *   trackingArea = [[NSTrackingArea alloc] initWithRect:theRect
                                                    options: (NSTrackingMouseEnteredAndExited  | NSTrackingActiveInKeyWindow  |NSTrackingActiveAlways)
                                                      owner:self userInfo:nil];
        [self addTrackingArea:trackingArea];
    }

    return self;
}

#define menuItem ([self enclosingMenuItem])

- (void) drawRect: (NSRect) rect {


    BOOL isHighlighted = [menuItem isHighlighted];
    if (isHighlighted) {
        //this nslog never happens
        NSLog(@"it's highlighted");
}



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


    NSLog(@"you clicked the %ld item",[m indexOfItem: mitem]);
}
@end
NSMenuItem子类:
(我在此处的自定义视图上添加子视图,以便可以通过
NSMenuItem
实例访问控件)

这是应用程序代理:

@interface AppDelegate : NSObject <NSApplicationDelegate>{

    NSStatusItem *statusItem;
    IBOutlet NSMenu *theMenu;
}

@property (assign) IBOutlet NSWindow *window;

@end  
#import "customItem.h"
@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

}

- (void)awakeFromNib{

    statusItem = [[NSStatusBar systemStatusBar]
                  statusItemWithLength:NSSquareStatusItemLength];
    NSBundle *bundle = [NSBundle mainBundle];

    NSImage *statusImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"barIcon" ofType:@"png"]];
   NSImage  *highlightImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"barIcon_H" ofType:@"png"]];

    [statusItem setImage:statusImage];
    [statusItem setAlternateImage:highlightImage];


    [statusItem setMenu:theMenu];

    [theMenu removeAllItems];
     customItem *mi = [[customItem alloc] init];

   [theMenu addItem:mi];
   customItem *mi2 = [[customItem alloc] init];
   [theMenu addItem:mi2];  
}
@end
@接口AppDelegate:NSObject{
NSStatusItem*statusItem;
IBNSMENU*菜单;
}
@属性(分配)窗口*窗口;
@结束
#导入“customItem.h”
@实现AppDelegate
-(无效)ApplicationIDFinishLaunching:(NSNotification*)通知
{
}
-(无效)从NIB中唤醒{
statusItem=[[NSStatusBar系统状态栏]
statusItemWithLength:NSSquareStatusItemLength];
NSBundle*bundle=[NSBundle mainBundle];
NSImage*statusImage=[[NSImage alloc]initWithContentsOfFile:[bundle pathForResource:@“barIcon”类型:@“png”];
NSImage*highlightImage=[[NSImage alloc]initWithContentsOfFile:[bundle pathForResource:@“barIcon_H”of type:@“png”];
[statusItem setImage:statusImage];
[statusItem setAlternateImage:highlightImage];
[状态项设置菜单:菜单];
[菜单删除所有项];
customItem*mi=[[customItem alloc]init];
[菜单附加项:mi];
customItem*mi2=[[customItem alloc]init];
[菜单附加项:mi2];
}
@结束

这就是我得到的:

好的,我想我明白了。
我在
NSView
子类中添加了一个公共bool变量。
然后我用

-(void)mouseEntered:(NSEvent *)theEvent

将变量设置为
YES
NO
。在设置了我使用的变量之后

[self setNeedsDisplay:YES] 
召唤

-(void) drawRect: (NSRect) rect 

这就是我让它工作的方式:)

无需添加布尔值或其他任何内容,您可以从附加到
NSMenuItem的自定义
NSView
中执行此操作

- (void)drawRect:(NSRect)rect {

[super drawRect:rect];

//Handle the hightlight
if ([[self enclosingMenuItem] isHighlighted])
{
    [self.lbl_title setTextColor:[NSColor whiteColor]];
    [self.lbl_amount setTextColor:[NSColor colorWithDeviceRed:151.0f/255.0f green:164.0f/255.0f blue:179.0f/255.0f alpha:1.0f]];
    [[NSColor selectedMenuItemColor] setFill];
}
else
{
    [self.lbl_title setTextColor:[NSColor blackColor]];
    [self.lbl_amount setTextColor:[NSColor whiteColor]];
    [[self backgroundColor] setFill];
}
NSRectFill(rect);}

以下是在不保留局部变量的情况下更改背景颜色(突出显示项目)并强制视图再次绘制的正确方法

-(void)mouseEntered:(NSEvent *)event {
    self.layer.backgroundColor = [[NSColor blueColor] colorWithAlphaComponent:0.3].CGColor;
    [theLabel setTextColor:[NSColor whiteColor]];
}

-(void)mouseExited:(NSEvent *)event {
    self.layer.backgroundColor = [NSColor clearColor].CGColor;
    [theLabel setTextColor:[NSColor blackColor]];
}
在更改图层背景颜色之前,请确保您还设置了
[self-setWantsLayer:YES]

-(void)mouseEntered:(NSEvent *)event {
    self.layer.backgroundColor = [[NSColor blueColor] colorWithAlphaComponent:0.3].CGColor;
    [theLabel setTextColor:[NSColor whiteColor]];
}

-(void)mouseExited:(NSEvent *)event {
    self.layer.backgroundColor = [NSColor clearColor].CGColor;
    [theLabel setTextColor:[NSColor blackColor]];
}