选择后如何刷新自定义NSMenuItem视图? [英] How to flash a custom NSMenuItem view after selection?

查看:186
本文介绍了选择后如何刷新自定义NSMenuItem视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将视图分配给NSMenuItem并进行一些自定义绘制.基本上,我会在当前选择的菜单项旁边添加一个删除按钮.但是我希望我的自定义菜单项在所有其他方面看起来和行为都像常规菜单项.根据文档:

I need to assign a view to an NSMenuItem and do some custom drawing. Basically, I'm adding a little delete button next to the currently selected menu item, among other things. But I want my custom menu item to look and behave like a regular menu item in all other ways. According to the doc:

带有视图的菜单项不会绘制 其标题,状态,字体或其他 标准工程图属性,以及 分配图纸责任 完全在视图中.

A menu item with a view does not draw its title, state, font, or other standard drawing attributes, and assigns drawing responsibility entirely to the view.

好,所以我不得不复制状态列的外观和选择渐变,这并不难.我遇到麻烦的部分是选择菜单项后闪烁"或闪烁"的方式.我正在使用NSTimer尝试模仿这个小动画,但是感觉很差.它闪烁多少次?我应该使用什么时间间隔?我做了很多尝试,感觉很不正常.

Ok, so I had to duplicate the look of the state column and the selection gradient, which wasn't that hard. The part I'm having trouble with is the way the menu item "flashes" or "blinks" after it is selected. I'm using an NSTimer to try to mimic this little animation, but it just feels off. How many times does it blink? What time interval should I use? I've experimented a lot and it just feels out of whack.

有没有人做过此事,或者对如何向菜单项添加按钮有其他建议?也许应该有一个仅用于自定义可可绘画的堆栈交换站点...

Has anyone done this before or have other suggestions on how to add a button to a menu item? Maybe there should be a stack exchange site just for custom cocoa drawing...

推荐答案

我知道这已经超过1年了,但这是我的Google搜索上的第一个热门搜索,但没有得到解答,因此为了方便起见,我发布了答案那些仍在寻找解决方案的人.

I know this is over a year old, but this was the first hit on my Google search and was unanswered, so I'm posting my answer for sake of those still looking for a solution.

对于我的应用程序,我将Core Animation与自定义NSView一起用于NSMenuItem视图.我创建了一个新的基于图层的视图,设置了背景色,并将其添加到了我的自定义视图中.然后,我对图层(闪烁的部分)进行了动画处理.然后在-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag回调中,我删除了覆盖层并关闭了菜单.这与默认的NSMenu闪存并不完全匹配,但我希望37Signals/Stack Overflow 黄色渐变技术,所以它对我有用.它在代码中:

For my app, I used Core Animation with a custom NSView for the NSMenuItem view. I created a new layer-backed view, set the background color, and added it to my custom view. I then animated the layer (the flashing part). Then in the -(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag callback, I removed the overlay and closed the menu. This doesn't perfectly match the default NSMenu's flash, but I wanted a 37Signals/Stack Overflow Yellow Fade Technique, so it works for me. Here it is in code:

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

这篇关于选择后如何刷新自定义NSMenuItem视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆