by Matt Long
原文地址: http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
乍一看, UIButton從定制的角度來說基本上不會提供你所想要的東西。因此程序員們在用IB設定按鈕的Background屬性時,不得不借助圖形工具以創建按鈕的背景圖。這也是不錯的解決方案,但正如帖子中所述,CoreAnimation layers有一種更簡單的方法,不需要你創建任何圖片。
一、改變背景色
在IB中,當你使用Custom類型的Button時,你可以指定按鈕的背景色。但當你運行時按鈕就失去了圓角特性,你看到的僅僅是一個方塊。因為custombutton沒有定義任何屬性默認值。你必須自己去定義它們,這就需要使用Core Animation Layer。
提示:編寫代碼之前,需要導入QuartzCore框架到工程中,然後#import<QuartzCore/QuartzCore.h>。我會通常會把它放在.pch文件中。
IB沒有干的事情,你只能通過代碼來做。例如,如果你想做一個圓角且紅色背景的按鈕,你需要將按鈕鏈接到你的viewcontroller的出口中,然後在Xcode中通過它的layer屬性修改按鈕的下列屬性。
[[button layer] setCornerRadius:8.0f];
[[button layer] setMasksToBounds:YES];
[[button layer] setBorderWidth:1.0f];
上述代碼將layer的圓角半徑設為8.0,-setMasksToBounds:方法告訴layer將位於它之下的layer都遮蓋住。這是必須的,這樣會使圓角不被遮住。
最後,將border設為1.0,將顯示出按鈕的邊框。默認邊框色為黑色,你可以用-setBorderColor:方法修改為其他顏色,參數使用CGColorRef類型(例如[[UIColorgreenColor]CGColor]會顯示綠色邊框)。
iPhone 開發技巧 : 任何UIView都有可能是圓角的。所有的UIView都有一個root layer。簡單地在view的layer上調用-setCornerRadius:和-setMasksToBounds:方法,你就會獲得圓角效果。
可在IB或者通過代碼來改變背景色。可使用兩種代碼,用layer或者直接在UIView上setBackgroundColor:
// CoreAnimation way
[[button layer] setBackgroundColor:[[UIColor redColor]CGColor]];
// UIView way
[button setBackgroundColor:[UIColorredColor]];
二者區別在於:layer使用CGColorRef參數,UIView使用UIColor參數。
二、漸變色
示例程序使用了一些很亮很花哨的顏色漸變效果,建議你不要學我。兩種顏色之間過渡得更自然一些會更好,當然你也可以完全憑個人喜好。
為達到這樣的漸變效果,我使用了CAGradientLayer並把它加到了按鈕的layer樹中。實際上,為了演示,我創建了一個UIButton子類,封裝了CAGradientLayer的創建和繪制,實現如下。
#import"ColorfulButton.h"
@implementation ColorfulButton
@synthesize _highColor;
@synthesize _lowColor;
@synthesize gradientLayer;
- (void)awakeFromNib;
{
// Initialize the gradient layer
gradientLayer =[[CAGradientLayer alloc] init];
// Set itsbounds to be the same of its parent
[gradientLayersetBounds:[self bounds]];
// Centerthe layer inside the parent layer
[gradientLayersetPosition:
CGPointMake([self bounds].size.width/2,
[self bounds].size.height/2)];
// Insertthe layer at position zero to make sure the
// text of the button is notobscured
[[self layer] insertSublayer:gradientLayer atIndex:0];
// Set the layer's corner radius
[[self layer] setCornerRadius:8.0f];
// Turn onmasking
[[self layer] setMasksToBounds:YES];
// Display aborder around the button
// with a 1.0pixel width
[[self layer] setBorderWidth:1.0f];
}
- (void)drawRect:(CGRect)rect
{
if (_highColor && _lowColor){
//Set the colors for the gradient to the
// two colorsspecified for high and low
[gradientLayer setColors:
[NSArrayarrayWithObjects:
(id)[_highColor CGColor],
(id)[_lowColor CGColor],nil]];
}
[superdrawRect:rect];
}
- (void)setHighColor:(UIColor*)color{
// Set thehigh color and repaint
[selfset_highColor:color];
[[selflayer] setNeedsDisplay];
}
- (void)setLowColor:(UIColor*)color{
// Set thelow color and repaint
[selfset_lowColor:color];
[[selflayer] setNeedsDisplay];
}
- (void)dealloc {
// Releaseour gradient layer
[gradientLayerrelease];
[superdealloc];
}
@end
現在,我在IB中創建了一個按鈕,並將class設置為ColorfulButton,隨後在viewcontroller中設置一個出口。
如果不設置漸變色,按鈕將用IB中指定的背景色進行渲染。如果想使用漸變色特性,則我需要在viewcontroller中設置其對應屬性:
- (void)viewDidLoad {
[superviewDidLoad];
[button1setHighColor:[UIColor redColor]];
[button1setLowColor:[UIColor orangeColor]];
[button2setHighColor:[UIColor blueColor]];
[button2setLowColor:[UIColor lightGrayColor]];
[button3setHighColor:[UIColor yellowColor]];
[button3setLowColor:[UIColor purpleColor]];
[button4setHighColor:[UIColor cyanColor]];
[button4setLowColor:[UIColor magentaColor]];
}
在這個demo中有4個按鈕。這些按鈕在接口中聲明如下:
#import<UIKit/UIKit.h>
#import"ColorfulButton.h"
@interface ColorfulButtonsViewController :UIViewController {
IBOutlet ColorfulButton *button1;
IBOutlet ColorfulButton *button2;
IBOutlet ColorfulButton *button3;
IBOutlet ColorfulButton *button4;
}
@end
CAGrandientLayer 支持把顏色數組加到它的colors中,並自動用這些顏色以平均分布的形式做線型漸變。它還允許指定分布模式,為簡單起見,我只用了兩種顏色:highColor、lowColor。如果你想加入更復雜的顏色漸變,你可以修改ColorfulButton類。
摘自 kmyhy的專欄