2011-02-01 34 views
1

我需要将视图分配给NSMenuItem并执行一些自定义绘图。基本上,我在当前选择的菜单项旁边添加一个删除按钮,等等。但是我希望我的自定义菜单项看起来像其他所有方式的常规菜单项一样。据商务部:如何在选择后刷新自定义NSMenuItem视图?

与视图中的菜单项不画 其标题,状态,字体,或其他 标准图纸属性, 受让人绘图责任 完全的视图。

好的,所以我不得不重复状态列和选择渐变的外观,这并不困难。我遇到困难的部分是菜单项在选中后闪烁或闪烁的方式。我正在使用NSTimer来模仿这个小动画,但它感觉不到。它眨眼多少次?我应该使用什么时间间隔?我已经做了很多实验,只是感觉不合时宜。

有没有人以前做过或有其他建议如何将一个按钮添加到菜单项?也许应该有一个堆栈交换网站只是为了定制可可绘图...

+0

当按下快捷键时(如果有),还应该在菜单栏中闪烁菜单项的父项。 – 2011-02-01 16:39:27

+0

我正在寻找选定的项目渐变代码(或只是开始和结束颜色),你能分享它吗?提前致谢。 – 2011-03-05 14:24:29

回答

3

我知道这已经过了一年多了,但这是我的谷歌搜索的第一次打击,没有回答,所以我张贴我的答案为了那些仍在寻找解决方案的人。

对于我的应用程序,我使用Core Animation和NSMenuItem视图的自定义NSView。我创建了一个新的图层背景视图,设置背景颜色,并将其添加到我的自定义视图中。然后,我为该图层(闪烁的部分)进行了动画处理。然后在-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag回调中,我删除了叠加并关闭了菜单。这并不完全符合默认NSMenu的闪存,但我想要一个37Signals /堆栈溢出Yellow Fade Technique,所以它适用于我。这里是代码:

-(void) mouseUp:(NSEvent *)theEvent { 
    CALayer *layer = [CALayer layer]; 
    [layer setDelegate:self]; 
    [layer setBackgroundColor:CGColorCreateGenericRGB(0.0, 0.0, 1.0, 1.0)]; 

    selectionOverlayView = [[NSView alloc] init]; 
    [selectionOverlayView setWantsLayer:YES]; 
    [selectionOverlayView setFrame:self.frame]; 
    [selectionOverlayView setLayer:layer]; 
    [[selectionOverlayView layer] setNeedsDisplay]; 
    [selectionOverlayView setAlphaValue:0.0]; 
    [self addSubview:selectionOverlayView]; 

    CABasicAnimation *alphaAnimation1 = [CABasicAnimation animationWithKeyPath: @"alphaValue"]; 
    alphaAnimation1.beginTime = 0.0; 
    alphaAnimation1.fromValue = [NSNumber numberWithFloat: 0.0]; 
    alphaAnimation1.toValue = [NSNumber numberWithFloat: 1.0]; 
    alphaAnimation1.duration = 0.07; 

    CABasicAnimation *alphaAnimation2 = [CABasicAnimation animationWithKeyPath: @"alphaValue"]; 
    alphaAnimation2.beginTime = 0.07; 
    alphaAnimation2.fromValue = [NSNumber numberWithFloat: 1.0]; 
    alphaAnimation2.toValue = [NSNumber numberWithFloat: 0.0]; 
    alphaAnimation2.duration = 0.07; 

    CAAnimationGroup *selectionAnimation = [CAAnimationGroup animation]; 
    selectionAnimation.delegate = self; 
    selectionAnimation.animations = [NSArray arrayWithObjects:alphaAnimation1, alphaAnimation2, nil]; 
    selectionAnimation.duration = 0.14; 
    [selectionOverlayView setAnimations:[NSDictionary dictionaryWithObject:selectionAnimation forKey:@"frameOrigin"]]; 

    [[selectionOverlayView animator] setFrame:[selectionOverlayView frame]]; 
} 

-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 
    [selectionOverlayView removeFromSuperview]; 

    NSMenuItem *enclosingMenuItem = [self enclosingMenuItem]; 
    NSMenu *enclosingMenu = [enclosingMenuItem menu]; 
    [enclosingMenu cancelTracking]; 
    [enclosingMenu performActionForItemAtIndex:[enclosingMenu indexOfItem:enclosingMenuItem]]; 
} 
0

这是我的代码,闪烁自定义菜单项。

int16_t fireTimes; 
BOOL  isSelected; 

- (void)mouseEntered:(NSEvent*)event 
{ 
    isSelected = YES; 
} 

- (void)mouseUp:(NSEvent*)event { 

    fireTimes = 0; 

    isSelected = !isSelected; 
    [self setNeedsDisplay:YES]; 

    NSTimer *timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(animateDismiss:) userInfo:nil repeats:YES]; 

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; 
} 

-(void)animateDismiss:(NSTimer *)aTimer 
{ 
    if (fireTimes <= 2) { 
     isSelected = !isSelected; 
     [self setNeedsDisplay:YES]; 
    } else { 
     [aTimer invalidate]; 
     [self sendAction]; 
    } 

    fireTimes++; 
} 

- (void)drawRect:(NSRect)dirtyRect { 

    if (isSelected) { 
     NSRect frame = NSInsetRect([self frame], -4.0f, -4.0f); 
     [[NSColor selectedMenuItemColor] set]; 
     NSRectFill(frame); 
     [itemNameFld setTextColor:[NSColor whiteColor]]; 
    } else { 
     [itemNameFld setTextColor:[NSColor blackColor]]; 
    } 

} 

- (void)sendAction 
{ 
    NSMenuItem *actualMenuItem = [self enclosingMenuItem]; 

    [NSApp sendAction:[actualMenuItem action] to:[actualMenuItem target] from:actualMenuItem]; 

    NSMenu *menu = [actualMenuItem menu]; 
    [menu cancelTracking]; 

    // [self setNeedsDisplay:YES]; // I'm not sure of this 
} 
0

实际上可以让您的自定义视图像常规NSMenuItem一样闪烁,而无需手动实现动画。

注意:这使用私人API,并修复了少数与自定义视图有关的其他奇怪的NSMenuItem怪癖。

NSMenuItem.h

#import <AppKit/AppKit.h> 

@interface NSMenuItem() 
    - (BOOL)_viewHandlesEvents; 
@end 

桥接报头

#import "NSMenuItem.h" 

MenuItem.swift

class MenuItem: NSMenuItem { 
    override func _viewHandlesEvents() -> Bool { 
     return false 
    } 
} 

钍API真的应该是公开的,如果你没有为App Store开发,可能值得看看。

相关问题