我想在我的 Mac 应用程序中为按钮的宽度设置动画,同时有一个背景图像和一个前景图像。为此,我使用了@kgn 很棒的库 BBlock ( https://github.com/kgn/BBlock )。
问题是背景图像似乎被画在一个后面,所以当按钮缩小时,你甚至看不到背景图像动画,它似乎被切断了。
如果我只使用 setImage,这种“动画化”宽度变化的方式是有效的,但是我没有得到背景图像的好处。
我制作了一个自定义按钮,可以逐步缩放按钮(基本上是动画)。它每次运行都会将按钮的大小更改一个像素,并将图像、背景图像和备用背景图像也更改一个像素:
- (void)scaleTestButtonUntilWidth:(int)width{
[NSTimer scheduledTimerRepeats:YES withTimeInterval:timeInterval andBlock:^{
if (self.width == width) {
return;
}
int newSize;
if (width > self.width) {
newSize = self.width += 1;
}else if (width < self.width){
newSize = self.width -= 1;
}
self.width = newSize;
[self setImage:self.image];
[self setAlternateBackgroundImage:[self alternateBGImage]];
[self setBackgroundImage:[self BGImage]];
}];
}
setBackgroundImage 看起来像这样,setAlternateBackgroundImage 的实现是相同的:
- (void)setBackgroundImage:(NSImage *)backgroundImage{
[self setImage:[self imageWithBackgroundImage:backgroundImage
andIcon:self.image]];
[self setButtonType:NSMomentaryChangeButton];
[self setBordered:NO];
}
它调用实际绘制图像的方法:
- (NSImage *)imageWithBackgroundImage:(NSImage *)background andIcon:(NSImage *)icon{
return [NSImage imageForSize:background.size withDrawingBlock:^{
NSRect bounds = NSZeroRect;
bounds.size = background.size;
NSRect iconRect = NSZeroRect;
iconRect.size = icon.size;
iconRect.origin.x = round(background.size.width*0.5f-iconRect.size.width*0.5f);
iconRect.origin.y = round(background.size.height*0.5f-iconRect.size.height*0.5f);
[background drawInRect:bounds fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
[icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}];
}
借助此方法:
+ (NSImage *)imageForSize:(NSSize)size withDrawingBlock:(void(^)())drawingBlock{
if(size.width <= 0 || size.width <= 0){
return nil;
}
NSImage *image = [[NSImage alloc] initWithSize:size];
[image lockFocus];
drawingBlock();
[image unlockFocus];
#if !__has_feature(objc_arc)
return [image autorelease];
#else
return image;
#endif
}