首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将动画图标添加到OS X状态栏?

如何将动画图标添加到OS X状态栏?
EN

Stack Overflow用户
提问于 2011-07-07 22:06:45
回答 3查看 8.2K关注 0票数 18

我想在Mac OS状态栏中放置一个图标作为我的cocoa应用程序的一部分。我现在要做的是:

代码语言:javascript
复制
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帧),我该怎么做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-07 23:01:14

您需要在NSStatusItem上重复调用-setImage:,每次传入不同的图像。执行此操作的最简单方法是使用NSTimer和实例变量来存储动画的当前帧。

如下所示:

代码语言:javascript
复制
/*

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;
    }
}
票数 28
EN

Stack Overflow用户

发布于 2015-04-30 22:48:32

我重写了Rob的解决方案,以便我可以重用它:

我有9帧的数量和所有的图像名称有最后一个数字作为帧编号,以便我可以重置图像每次动画的图标。

代码语言:javascript
复制
//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

使用方法:

  1. 符合StatusMenu类中的协议

//创建IntervalAnimator对象animator = [IntervalAnimator alloc ];animator setDelegate:self;animator setNumberOfFrames:9;animator startAnimating;

  • Implement协议方法

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

票数 5
EN

Stack Overflow用户

发布于 2018-11-03 01:17:24

最近在一个简单的项目中不得不做一些类似的事情,所以我在Swift中发布了我的个人版本:

代码语言:javascript
复制
class StatusBarIconAnimationUtils: NSObject {
    private var currentFrame = 0
    private var animTimer : Timer
    private var statusBarItem: NSStatusItem!
    private var imageNamePattern: String!
    private var imageCount : Int!

    init(statusBarItem: NSStatusItem!, imageNamePattern: String, imageCount: Int) {
        self.animTimer = Timer.init()
        self.statusBarItem = statusBarItem
        self.imageNamePattern = imageNamePattern
        self.imageCount = imageCount
        super.init()
    }

    func startAnimating() {
        stopAnimating()
        currentFrame = 0
        animTimer = Timer.scheduledTimer(timeInterval: 5.0 / 30.0, target: self, selector: #selector(self.updateImage(_:)), userInfo: nil, repeats: true)
    }

    func stopAnimating() {
        animTimer.invalidate()
        setImage(frameCount: 0)
    }

    @objc private func updateImage(_ timer: Timer?) {
        setImage(frameCount: currentFrame)
        currentFrame += 1
        if currentFrame % imageCount == 0 {
            currentFrame = 0
        }
    }

    private func setImage(frameCount: Int) {
        let imagePath = "\(imageNamePattern!)\(frameCount)"
        print("Switching image to: \(imagePath)")
        let image = NSImage(named: NSImage.Name(imagePath))
        image?.isTemplate = true // best for dark mode
        DispatchQueue.main.async {
            self.statusBarItem.button?.image = image
        }
    }
}

用法:

代码语言:javascript
复制
private let statusItem = 
    NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)

// Assuming we have a set of images with names: statusAnimatedIcon0, ..., statusAnimatedIcon6
private lazy var iconAnimation = 
    StatusBarIconAnimationUtils.init(statusBarItem: statusItem, imageNamePattern: "statusAnimatedIcon", 
    imageCount: 7)

private func startAnimation() {
    iconAnimation.startAnimating()
}

private func stopAnimating() {
    iconAnimation.stopAnimating()
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6611912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档