【问题标题】:Change background color on hover on a NSMenuItem with custom NSView使用自定义 NSView 更改悬停在 NSMenuItem 上的背景颜色
【发布时间】:2013-07-12 00:38:41
【问题描述】:

事情是这样的:

我创建了一个自定义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 customItem : NSMenuItem{

}

-(void)setTheText:(NSString*)theString;

@property NSTextField *theLabel;
@end
#import "customItem.h"
#import "customView.h"
@implementation customItem
@synthesize theLabel;
-(id)init{

    if (self){

        customView *cv = [[customView alloc] init];
        theLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 8, 130, 17)];
        [theLabel setEditable:NO];
        [theLabel setBordered:NO];
        NSButton *myButton = [[NSButton alloc] initWithFrame:NSMakeRect(170, 7, 20, 20)];
        NSButton *myButton1 = [[NSButton alloc] initWithFrame:NSMakeRect(150, 7, 20, 20)];

        [myButton setBezelStyle:NSCircularBezelStyle]; 
        [myButton1 setBezelStyle:NSCircularBezelStyle]; 

        [myButton setTitle:@""];
        [myButton1 setTitle:@""];
        [cv addSubview:myButton];
        [cv addSubview:myButton1];
        [cv addSubview:theLabel];
        [self setView:cv];
        [theLabel setStringValue:@"A Value "];

    }

    return self;
}

-(void)setTheText:(NSString *)theString{

    [theLabel setStringValue:theString];
}


@end   

这是应用代理:

@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

这是我得到的:

【问题讨论】:

    标签: objective-c macos cocoa nsview nsmenuitem


    【解决方案1】:

    无需添加布尔值或其他任何内容,您可以在附加到您的 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);}
    

    【讨论】:

      【解决方案2】:

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

      -(void)mouseEntered:(NSEvent *)theEvent
      

      -(void)mouseExited:(NSEvent *)theEvent
      

      将变量设置为YESNO。设置变量后我使用了

      [self setNeedsDisplay:YES] 
      

      打电话

      -(void) drawRect: (NSRect) rect 
      

      这就是我的工作方式:)

      【讨论】:

        【解决方案3】:

        这是更改背景颜色(突出显示项目)而不维护局部变量并强制视图再次绘制的正确方法,

        -(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]

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-27
          • 1970-01-01
          • 1970-01-01
          • 2014-04-09
          • 2013-08-10
          • 1970-01-01
          • 1970-01-01
          • 2020-05-10
          相关资源
          最近更新 更多