1

Mac アプリでボタンの幅をアニメーション化し、同時に背景画像と前景画像を作成したいと考えています。そのために、@kgn の素晴らしいライブラリ BBlock ( https://github.com/kgn/BBlock ) を使用しています。

問題は、背景画像が互いに後ろに描画されているように見えるため、ボタンを縮小すると背景画像のアニメーションさえ見えず、途切れているように見えることです。 ボタン画像のカットオフ

幅の変更を「アニメーション化」するこの方法は、setImage を使用するだけで機能しますが、背景画像を使用する利点は得られません。

ボタンを段階的に拡大縮小するカスタム ボタンを作成しました (基本的にはアニメーション化します)。実行ごとにボタンのサイズを 1 ピクセルずつ変更し、画像、背景画像、代替背景画像も 1 ピクセルずつ変更します。

- (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
}
4

2 に答える 2

0

グラフィックコンテキストを保存して復元してみてください。

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);

    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
    CGContextSaveGState(context);        
    [background drawInRect:bounds fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    [icon drawInRect:iconRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    CGContextRestoreGState(context);
}];
于 2013-02-20T21:37:55.323 に答える