定制按钮及CALayer
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" <
补充:移动开发 , IOS ,