2011-07-07 10 views
16

Chcę umieścić ikonę w pasku stanu Mac OS jako część mojej aplikacji kakao. Co mam teraz zrobić to:Jak dodać animowaną ikonę do paska stanu OS X?

NSStatusBar *bar = [NSStatusBar systemStatusBar]; 

sbItem = [bar statusItemWithLength:NSVariableStatusItemLength]; 
[sbItem retain]; 

[sbItem setImage:[NSImage imageNamed:@"Taski_bar_icon.png"]]; 
[sbItem setHighlightMode:YES]; 
[sbItem setAction:@selector(stopStart)]; 

ale jeśli chcę być animowana ikona (3-4 klatek), w jaki sposób mogę to zrobić?

+2

Cóż, chcę sprawić wrażenie, że aplikacja przetwarza dane - zdarza się to rzadko, ale może być dobrze wiedzieć. A może nie powinienem? – kender

+8

To ważne użycie. Heck, Time Machine to robi. –

+4

Myślę, że Dropbox radzi sobie z tym całkiem dobrze. Jest subtelny, ale mówi, że rzeczy się aktualizują. –

Odpowiedz

27

Będziesz musiał wielokrotnie wywoływać numer -setImage: na swoim NSStatusItem, za każdym razem przekazując inne zdjęcie. Najłatwiej to zrobić przy pomocy NSTimer i zmiennej instancji do przechowywania bieżącej klatki animacji.

coś takiego:

/* 

assume these instance variables are defined: 

NSInteger currentFrame; 
NSTimer* animTimer; 

*/ 

- (void)startAnimating 
{ 
    currentFrame = 0; 
    animTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 target:self selector:@selector(updateImage:) userInfo:nil repeats:YES]; 
} 

- (void)stopAnimating 
{ 
    [animTimer invalidate]; 
} 

- (void)updateImage:(NSTimer*)timer 
{ 
    //get the image for the current frame 
    NSImage* image = [NSImage imageNamed:[NSString stringWithFormat:@"image%d",currentFrame]]; 
    [statusBarItem setImage:image]; 
    currentFrame++; 
    if (currentFrame % 4 == 0) { 
     currentFrame = 0; 
    } 
} 
+0

Czy jest również możliwe umieszczenie NSView lub NSImageView na pasku stanu? Jak to zrobić? – zsong

+0

czy musisz powiedzieć animTimer, aby strzelał przez [animTimer fire], czy jest to automatyczne? –

+1

Metody '+ scheduledTimerWithTimeInterval: ...' dodadzą timer do pętli uruchamiania (jest to bit '' zaplanowany'), więc nie musisz strzelać samemu. –

5

I ponownie napisał rozwiązanie Roba tak, że można go ponownie użyć:

Mam liczba klatek 9 i wszystkie nazwy obrazów ma ostatnią cyfrę jako numer ramy tak że mogę resetować obraz za każdym razem, aby animować ikonę.

//IntervalAnimator.h 

    #import <Foundation/Foundation.h> 

@protocol IntervalAnimatorDelegate <NSObject> 

- (void)onUpdate; 

@end 


@interface IntervalAnimator : NSObject 
{ 
    NSInteger numberOfFrames; 
    NSInteger currentFrame; 
    __unsafe_unretained id <IntervalAnimatorDelegate> delegate; 
} 

@property(assign) id <IntervalAnimatorDelegate> delegate; 
@property (nonatomic) NSInteger numberOfFrames; 
@property (nonatomic) NSInteger currentFrame; 

- (void)startAnimating; 
- (void)stopAnimating; 
@end 

#import "IntervalAnimator.h" 

@interface IntervalAnimator() 
{ 
    NSTimer* animTimer; 
} 

@end 

@implementation IntervalAnimator 
@synthesize numberOfFrames; 
@synthesize delegate; 
@synthesize currentFrame; 

- (void)startAnimating 
{ 
    currentFrame = -1; 
    animTimer = [NSTimer scheduledTimerWithTimeInterval:0.50 target:delegate selector:@selector(onUpdate) userInfo:nil repeats:YES]; 
} 

- (void)stopAnimating 
{ 
    [animTimer invalidate]; 
} 

@end 

Jak używać:

  1. Zgodne z protokołem w swojej klasie StatusMenu

    //create IntervalAnimator object 
    
    animator = [[IntervalAnimator alloc] init]; 
    
    [animator setDelegate:self]; 
    
    [animator setNumberOfFrames:9]; 
    
    [animator startAnimating]; 
    
  2. Wdrożenie metody protokół

    -(void)onUpdate { 
    
        [animator setCurrentFrame:([animator currentFrame] + 1)%[animator numberOfFrames]]; 
    
        NSImage* image = [NSImage imageNamed:[NSString stringWithFormat:@"icon%ld", (long)[animator currentFrame]]]; 
    
        [statusItem setImage:image]; 
    
    } 
    
Powiązane problemy