iOS - 更改UIButton或自定义UIButton的渐变背景

时间:2014-04-07 09:23:53

标签: ios objective-c uibutton cagradientlayer

我使用.h文件创建了自己的类,来自UIButton:

@interface MenuButton : UIButton

- (void)changeBackground;

@end

在实现中,我试图添加一些方法来改变背景但到目前为止没有成功:

#import "MenuButton.h"
#import "GradientLayers.h"

@implementation MenuButton

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

- (id)initWithCoder:(NSCoder *)aDecoder;
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit;
{

    // Gradient background
    CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
    gradient.frame = [self layer].bounds;

    // Insert background
    [[self layer] insertSublayer:gradient atIndex:0];

    [[self layer] setCornerRadius:10.0f];
    [[self layer] setMasksToBounds:YES];
    [[self layer] setBorderWidth:2];
    [[self layer] setBorderColor:[[UIColor blackColor] CGColor]];

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // handle touch
    [super touchesEnded:touches withEvent:event];

    if ([self state] != UIControlStateSelected)
    {
        CAGradientLayer *gradient = [GradientLayers blackBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
    else
    {
        CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
}

- (void)changeBackground
{
    CAGradientLayer *gradient = [[[self layer] sublayers] firstObject];
    gradient = [GradientLayers blackBackground];
    [[self layer] insertSublayer:gradient atIndex:0];
    [self setNeedsDisplay];
}

@end

GradientLayer.m文件的一部分:

#import "GradientLayers.h"

@implementation GradientLayers

+ (CAGradientLayer*) blackBackground {
    // similar to darkBlueBackground
}

+ (CAGradientLayer*) darkBlueBackground {
    // Create colors
    UIColor *darkOp = [UIColor colorWithRed:0.039f green:0.106f blue:0.278f alpha:1.0];
    UIColor *lightOp = [UIColor colorWithRed:0.133f green:0.267f blue:0.65f alpha:1.0];

    // Create gradient
    CAGradientLayer *gradient = [CAGradientLayer layer];

    // Set colors
    gradient.colors = [NSArray arrayWithObjects:
                       (id)lightOp.CGColor,
                       (id)darkOp.CGColor,
                       nil];

    // Shadow
    gradient.shadowOffset = CGSizeMake(3.0f, 3.0f);
    gradient.shadowColor = [UIColor blackColor].CGColor;
    gradient.shadowOpacity = 0.6;
    gradient.shadowRadius = 10;

    // Other options
    gradient.borderWidth = 0.5f;
    gradient.borderColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0].CGColor;
    gradient.cornerRadius = 10;

    return gradient;
}

@end

我在commonInit中设置了带有darkBlueBackground的按钮。这不是问题。但是我想在用户点击按钮后更改它,到目前为止没有运气。如果我设置断点,我在touchesEnded或changeBackground但执行后按钮具有与以前相同的背景。那么如何将背景更改为另一个渐变背景?感谢

1 个答案:

答案 0 :(得分:4)

由于[self layer].sublayers数组按照前后顺序列出(https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/sublayers),通过在索引0处插入替换图层,您始终将其置于旧版本之后梯度。

您应该删除旧的渐变图层,然后添加新的渐变图层。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // handle touch
    [super touchesEnded:touches withEvent:event];

    // Remove old gradient here
    [[[[self layer] sublayers] objectAtIndex:0] removeFromSuperlayer];

    if ([self state] != UIControlStateSelected)
    {
        CAGradientLayer *gradient = [GradientLayers blackBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
    else
    {
        CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
}

- (void)changeBackground
{
    // Remove old gradient here
    [[[[self layer] sublayers] objectAtIndex:0] removeFromSuperlayer];

    CAGradientLayer *gradient = [[[self layer] sublayers] firstObject];
    gradient = [GradientLayers blackBackground];
    [[self layer] insertSublayer:gradient atIndex:0];
    [self setNeedsDisplay];
}

你真的应该更好地跟踪渐变,所以你不能经常删除并用相同的渐变替换它。也许只是显示和隐藏选定状态,它总是位于未突出显示的版本之上。