网站上有一些类似的问题,但我正在寻找具体而略有不同的东西 .
我按照这里给出的方向:http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/来创建UIButton的子类,以创建一个我可以指定渐变颜色的泛型类,而不是尝试使用静态图像 .
我遇到了一个问题,其中按钮层上的setMasksToBounds将允许A)显示阴影,但也允许渐变层显示超出圆角或B)渐变层剪切到圆角,但不是允许投影显示
我对这个问题的解决方案似乎很笨拙(尽管它有效)我想知道是否有人知道更好和/或更清洁的方法来完成同样的事情 . 这是我的代码:
CSGradientButton.h
#import <UIKit/UIKit.h>
@interface CSGradientButton : UIButton {
UIColor *_highColor;
UIColor *_lowColor;
CAGradientLayer *gradientLayer;
CALayer *wrapperLayer;
CGColorRef _borderColor;
}
@property (nonatomic, retain) UIColor *_highColor;
@property (nonatomic, retain) UIColor *_lowColor;
@property (nonatomic) CGColorRef _borderColor;
@property (nonatomic, retain) CALayer *wrapperLayer;
@property (nonatomic, retain) CAGradientLayer *gradientLayer;
- (void)setHighColor:(UIColor*)color;
- (void)setLowColor:(UIColor*)color;
- (void)setBorderColor:(CGColorRef)color;
- (void)setCornerRadius:(float)radius;
@end
CSGradient.m(有趣的部分,无论如何)
#import "CSGradientButton.h"
@implementation CSGradientButton
...
- (void)awakeFromNib
{
// Initialize the gradient wrapper layer
wrapperLayer = [[CALayer alloc] init];
// Set its bounds to be the same of its parent
[wrapperLayer setBounds:[self bounds]];
// Center the layer inside the parent layer
[wrapperLayer setPosition:
CGPointMake([self bounds].size.width/2,
[self bounds].size.height/2)];
// Initialize the gradient layer
gradientLayer = [[CAGradientLayer alloc] init];
// Set its bounds to be the same of its parent
[gradientLayer setBounds:[self bounds]];
// Center the layer inside the parent layer
[gradientLayer setPosition: CGPointMake([self bounds].size.width/2,
[self bounds].size.height/2)];
// Insert the layer at position zero to make sure the
// text of the button is not obscured
[wrapperLayer insertSublayer:gradientLayer atIndex:0];
[[self layer] insertSublayer:wrapperLayer atIndex:0];
// Set the layer's corner radius
[[self layer] setCornerRadius:0.0f];
[wrapperLayer setCornerRadius:0.0f];
// Turn on masking
[wrapperLayer setMasksToBounds:YES];
// Display a border around the button
// with a 1.0 pixel width
[[self layer] setBorderWidth:1.0f];
}
- (void)drawRect:(CGRect)rect
{
if (_highColor && _lowColor)
{
// Set the colors for the gradient to the
// two colors specified for high and low
[gradientLayer setColors:
[NSArray arrayWithObjects:
(id)[_highColor CGColor],
(id)[_lowColor CGColor], nil]];
}
[super drawRect:rect];
}
- (void)setCornerRadius:(float)radius
{
[[self layer] setCornerRadius:radius];
// and get the wrapper for the gradient layer too
[wrapperLayer setCornerRadius:radius];
}
- (void)setHighColor:(UIColor*)color
{
// Set the high color and repaint
[self set_highColor:color];
[[self layer] setNeedsDisplay];
}
- (void)setLowColor:(UIColor*)color
{
// Set the low color and repaint
[self set_lowColor:color];
[[self layer] setNeedsDisplay];
}
- (void)setBorderColor:(CGColorRef)color
{
[[self layer] setBorderColor:color];
[[self layer] setNeedsDisplay];
}
@end
如您所见,我添加了一个渐变图层可以安全遮盖的“包装”图层,而按钮视图的顶级CALayer可以在添加投影图时安全地设置masksToBounds = NO . 我添加了一个setCornerRadius:方法来允许顶层和'包装器'进行调整 .
所以,而不是做 [[myCustomButton layer] setCornerRadius:3.0f];
之类的事情,我只是说 [myCustomButton setCornerRadius:3.0f];
正如你所看到的那样,它希望 .
有没有更好的办法?
3 回答
这是我发现有一个圆角,渐变和阴影按钮的方式 . 此示例具有一个特定渐变,但显然可以用其他渐变替换 .
您也可以覆盖方法
+layerClass
以返回CAGradientLayer
类,而不是插入渐变图层 . 按钮的图层比该图层的图层要多,您可以轻松设置其颜色等 .我有一个类似的问题,但不是渐变,我有一个背景图像 . 我最终解决了它:
真正有趣的是,如果你有一个clearColor,因为shadowLayer.backgroundColor只是没有绘制 .