2

我使用 .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 但执行后按钮的背景与以前相同。那么如何将背景更改为另一个渐变背景?谢谢

4

1 回答 1

4

因为[self layer].sublayers数组以从后到前的顺序列出(https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/sublayers ),通过在 index 处插入替换层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];
}

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

于 2014-04-17T06:46:24.490 回答