2013-02-19 20 views
1

我想在我的Mac App中動畫我的按鈕的寬度,同時有一個背景圖像和一個前景圖像。爲此,我使用@ kgn的真棒圖書館BBlock(https://github.com/kgn/BBlock)。在drawInRect for Mac之前清空App

問題在於背景圖像似乎相互牽扯在一起,所以當按鈕縮小時,甚至看不到背景圖像動畫,並且它似乎被切斷。 Button Image Cut Off

這種「動畫」寬度變化的方式工作,如果我只是使用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 
} 
+0

沒有建議?在繪製新圖像之前,必須有某種方法可以清除背景。 – 2013-02-20 05:13:03

+0

這聽起來像是你實現NSImage + imageForSize:withDrawingBlock:的方式有問題。我假設你自己實現了一個類別,因爲它不是標準的NSImage方法。 – indragie 2013-02-20 07:05:33

回答

0

我不知道你會過得更好繼承NSButton和覆蓋drawRect

+0

感謝您的建議。我結束了這樣做 - http://stackoverflow.com/questions/15017047/checking-if-nsbutton-is-down-on-drawrect – 2013-02-22 22:09:38

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); 
}]; 
+0

不錯的建議。雖然沒有工作。這很奇怪,因爲它只適用於[self setImage:[self BGImage]]。然後我只是沒有選擇背景和前景圖像。如果我發佈整個代碼流,它會有幫助嗎?! – 2013-02-21 04:27:13