gpt4 book ai didi

cocoa - 动画 NSStatusItem

转载 作者:行者123 更新时间:2023-12-03 16:54:51 31 4
gpt4 key购买 nike

我在 NSStatusItem 对象中有一个自定义 View 。该 View 显示图标。它还可以显示进度,但您必须调用 [self.statusitemview setProgressValue:theValue];我有一组图标,它使用该值选择正确的图标。

这看起来非常不稳定,因为执行的进程并不总是发送更新。所以我想将其动画化。

我想像使用其他 cocoa 控件一样调用动画:[[self.statusItemView 动画师] setProgressValue:value];

如果可以的话

执行此操作的正确方法是什么?我不想使用 NSTimer。

编辑

图像是使用drawRect:方法绘制的

代码如下:

- (void)drawRect:(NSRect)dirtyRect
{
if (self.isHighlighted) {
[self.statusItem drawStatusBarBackgroundInRect:self.bounds withHighlight:YES];
}

[self drawIcon];
}

- (void)drawIcon {
if (!self.showsProgress) {
[self drawIconWithName:@"statusItem"];
} else {
[self drawProgressIcon];
}
}

- (void)drawProgressIcon {
NSString *pushed = (self.isHighlighted)?@"-pushed":@"";
int iconValue = ((self.progressValue / (float)kStatusItemViewMaxValue) * kStatusItemViewProgressStates);
[self drawIconWithName:[NSString stringWithFormat:@"statusItem%@-%d", pushed, iconValue]];
}

- (void)drawIconWithName:(NSString *)iconName {
if (self.isHighlighted && !self.showsProgress) iconName = [iconName stringByAppendingString:@"-pushed"];
NSImage *icon = [NSImage imageNamed:iconName];
NSRect drawingRect = NSCenterRect(self.bounds, icon);

[icon drawInRect:drawingRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
}


- (void)setProgressValue:(int)progressValue {
if (progressValue > kStatusItemViewMaxValue || progressValue < 0) {
@throw [NSException exceptionWithName:@"Invalid Progress Value"
reason:[NSString stringWithFormat:@"The value %d id invalid. Range {0 - %d}", progressValue, kStatusItemViewMaxValue]
userInfo:nil];
}

_progressValue = progressValue;
[self setNeedsDisplay:YES];
}

- (void)setShowsProgress:(BOOL)showsProgress {
if (!showsProgress) self.progressValue = 0;
_showsProgress = showsProgress;

[self setNeedsDisplay:YES];
}

这一定是可能的。由于Apple 的标准控件是使用drawRect: 绘制的,但具有流畅的动画...

最佳答案

要为自定义属性设置动画,您需要使 View 符合NSAnimatablePropertyContainer协议(protocol)。

然后,您可以将多个自定义属性设置为可动画(除了 NSView 已经支持的属性之外),然后您可以简单地使用 View 的 animator 代理为属性设置动画:

yourObject.animator.propertyName = finalPropertyValue;

除了使动画变得非常简单之外,它还允许您使用 NSAnimationContext 同时为多个对象设置动画:

[NSAnimationContext beginGrouping];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];

您还可以设置持续时间并提供完成处理程序 block :

[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5];
[[NSAnimationContext currentContext] setCompletionHandler:^{
NSLog(@"animation finished");
}];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];

对于标准的NSView对象,如果你想给 View 中的某个属性添加动画支持,你只需要重写 View 中的+defaultAnimationForKey:方法并返回属性的动画:

//declare the default animations for any keys we want to animate
+ (id)defaultAnimationForKey:(NSString *)key
{
//in this case, we want to add animation for our x and y keys
if ([key isEqualToString:@"x"] || [key isEqualToString:@"y"]) {
return [CABasicAnimation animation];
} else {
// Defer to super's implementation for any keys we don't specifically handle.
return [super defaultAnimationForKey:key];
}
}

我创建了一个简单的sample project展示了如何使用 NSAnimatablePropertyContainer 协议(protocol)同时为 View 的多个属性设置动画。

要成功更新,您的 View 所需要做的就是确保在修改任何可动画属性时调用 setNeedsDisplay:YES。然后,您可以在 drawRect: 方法中获取这些属性的值,并根据这些值更新动画。

关于cocoa - 动画 NSStatusItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12834092/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com