Как добавить анимированный значок в строку состояния 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 кадра), как мне это сделать?
Ответы
Ответ 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];
}