2011-02-01 65 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開發,可能值得看看。

相關問題