Подтвердить что ты не робот

Как добавить анимированный значок в строку состояния OS X?

Я хочу поместить значок в строку состояния Mac OS как часть моего приложения cocoa. Сейчас я делаю следующее:

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)];

но если я хочу, чтобы иконка была анимирована (3-4 кадра), как мне это сделать?

4b9b3361

Ответ 1

Вам нужно будет многократно называть -setImage: на вашем NSStatusItem, передавая другое изображение каждый раз. Самый простой способ сделать это - с помощью NSTimer и переменной экземпляра для хранения текущего кадра анимации.

Что-то вроде этого:

/*

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

Ответ 2

Я повторно написал решение Rob, чтобы его можно было повторно использовать:

У меня есть число кадров 9, и все имена изображений имеют последнюю цифру в качестве номера кадра, так что я могу reset изображение каждый раз анимации значка.

//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

Как использовать:

  • Соответствует протоколу в вашем классе StatusMenu

    //create IntervalAnimator object
    
    animator = [[IntervalAnimator alloc] init];
    
    [animator setDelegate:self];
    
    [animator setNumberOfFrames:9];
    
    [animator startAnimating];
    
  • Использовать метод протокола

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