UIButton带渐变,圆角,边框和阴影 [英] UIButton w/ gradient, rounded corners, border, and drop shadow

查看:169
本文介绍了UIButton带渐变,圆角,边框和阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

网站上有一些类似的问题,但我正在寻找具体而略有不同的东西。

There are a few similar questions on the site, but I'm looking for something specific and slightly different.

我按照这里给出的指示: http://www.cimgf.com/2010 / 01/28 / fun-with-uibuttons-and-core-animation-layers / 子类化UIButton以创建一个我可以指定渐变颜色的泛型类,而不是尝试使用静态图像。

I followed the direction given here: http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/ to subclass UIButton in order to create a generic class that I can specify the gradient colors on, rather than trying to use a static image.

我遇到了一个问题,按钮层上的setMasksToBounds要么允许
A)要显示的阴影,还要允许渐变层到显示超出圆角
OR
B)渐变层剪裁到圆角,但不允许投影显示

I ran into a problem where the setMasksToBounds on the button's layer would either allow A) the drop shadow to show, but also allow the gradient layer to show beyond the rounded corners OR B) the gradient layer to clip to the rounded corners, but not allow the drop shadow to show

我的这个问题的解决方案似乎很笨重(尽管它有效)我想知道是否有人知道更好和/或更清洁的方法来完成同样的事情。这是我的代码:

My solution to the problem seemed clunky and (although it works) I wanted to see if anyone knew of a better and/or cleaner way to accomplish the same thing. Here's my code:

CSGradientButton.h

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(无论如何,有趣的部分)

CSGradient.m (the interesting parts, anyway)

#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:方法来允许顶层和'包装器'进行调整。

As you can see, I add a 'wrapper' layer that the gradient layer can safely mask to, while the top level CALayer of the button view can safely set masksToBounds = NO when the dropshadow is added. I add a setCornerRadius: method to allow both the top layer and the 'wrapper' to adjust.

所以不要做像 [[myCustomButton layer] setCornerRadius:3.0f]; 我只是说 [myCustomButton setCornerRadius:3.0f]; 正如你所看到的,它可能不像我希望的那么干净。

So rather than doing something like [[myCustomButton layer] setCornerRadius:3.0f]; I just say [myCustomButton setCornerRadius:3.0f]; As you can see, it's not maybe as clean as I'm hoping.

还有更好的方法吗?

推荐答案

这是我发现有一个带圆角,渐变和阴影的按钮的方法。此示例有一个特定的渐变,但显然可以替换为其他渐变。

This is the way I found to have a button with rounded corner, gradient, and drop shadow. This example has one particular gradient, but can obviously be replaced with other gradients.

@implementation CustomButton

- (id)initWithFrame:(CGRect)frame
{
    if((self = [super initWithFrame:frame])){
        [self setupView];
    }

    return self;
}

- (void)awakeFromNib {
    [self setupView];
}

# pragma mark - main

- (void)setupView
{
    self.layer.cornerRadius = 10;
    self.layer.borderWidth = 1.0;
    self.layer.borderColor = [UIColor colorWithRed:167.0/255.0 green:140.0/255.0 blue:98.0/255.0 alpha:0.25].CGColor;
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowRadius = 1;
    [self clearHighlightView];

    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = self.layer.bounds;
    gradient.cornerRadius = 10;
    gradient.colors = [NSArray arrayWithObjects:
                         (id)[UIColor colorWithWhite:1.0f alpha:1.0f].CGColor,
                         (id)[UIColor colorWithWhite:1.0f alpha:0.0f].CGColor,
                         (id)[UIColor colorWithWhite:0.0f alpha:0.0f].CGColor,
                         (id)[UIColor colorWithWhite:0.0f alpha:0.4f].CGColor,
                         nil];
    float height = gradient.frame.size.height;
    gradient.locations = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:0.0f],
                            [NSNumber numberWithFloat:0.2*30/height],
                            [NSNumber numberWithFloat:1.0-0.1*30/height],
                            [NSNumber numberWithFloat:1.0f],
                            nil];
    [self.layer addSublayer:gradient];}

- (void)highlightView 
{
    self.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
    self.layer.shadowOpacity = 0.25;
}

- (void)clearHighlightView {
    self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
    self.layer.shadowOpacity = 0.5;
}

- (void)setHighlighted:(BOOL)highlighted
{
    if (highlighted) {
        [self highlightView];
    } else {
        [self clearHighlightView];
    }
    [super setHighlighted:highlighted];
}


@end

这篇关于UIButton带渐变,圆角,边框和阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆