我想在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帧),我该怎么做呢?
发布于 2011-07-07 23:01:14
您需要在NSStatusItem上重复调用-setImage:,每次传入不同的图像。执行此操作的最简单方法是使用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;
}
}发布于 2015-04-30 22:48:32
我重写了Rob的解决方案,以便我可以重用它:
我有9帧的数量和所有的图像名称有最后一个数字作为帧编号,以便我可以重置图像每次动画的图标。
//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使用方法:
//创建IntervalAnimator对象animator = [IntervalAnimator alloc ];animator setDelegate:self;animator setNumberOfFrames:9;animator startAnimating;
-(空)onUpdate{ [animator setCurrentFrame:(animator currentFrame + 1)%animator numberOfFrames];NSImage* numberOfFrames= [NSImage imageNamed:[NSString stringWithFormat:@"icon%ld",(long)animator currentFrame]];statusItem setImage: image;}
发布于 2018-11-03 01:17:24
最近在一个简单的项目中不得不做一些类似的事情,所以我在Swift中发布了我的个人版本:
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
}
}
}用法:
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()
}https://stackoverflow.com/questions/6611912
复制相似问题