1

我想让我的 iOS 应用程序中的按钮具有红色渐变。起初我使用图像来做到这一点,但后来意识到我可以使用 QuartzCore 框架来做到这一点。我有以下实现文件:

#import "RedButton.h"

@implementation RedButton

@synthesize gradientLayer = _gradientLAyer;

- (void)awakeFromNib;
{
    // Initialize the gradient layer
    self.gradientLayer = [[CAGradientLayer alloc] init];
    // Set its bounds to be the same of its parent
    [self.gradientLayer setBounds:[self bounds]];
    // Center the layer inside the parent layer
    [self.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
    [[self layer] insertSublayer:self.gradientLayer atIndex:0];

    // Set the layer's corner radius
    [[self layer] setCornerRadius:5.0f];
    // Turn on masking
    [[self layer] setMasksToBounds:YES];
    // Display a border around the button 
    // with a 1.0 pixel width
    [[self layer] setBorderColor:[UIColor colorWithRed:(158.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f].CGColor];
    [[self layer] setBorderWidth:1.0f];

    [self.gradientLayer setColors:[NSArray arrayWithObjects:
                               (id)[[UIColor colorWithRed:(214.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f] CGColor], 
                               (id)[[UIColor colorWithRed:(141.0f/255.0f) green:0.0f blue:0.0f alpha:1.0f] CGColor], nil]];

    [[self layer] setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect;
{
    [super drawRect:rect];
}

- (void)dealloc {
    // Release our gradient layer
    self.gradientLayer = nil;
    [super dealloc];
}
@end

第一个问题 - 我在这里使用 awakeFromNib 是否正确?还是我应该使用 initWithFrame?

第二个问题 - 最初我使用图像并使用界面构建器来设置按钮的默认状态和突出显示状态。现在我不使用图像,如何设置按钮的外观以在突出显示时更改?我只想反转渐变。

第三个问题 - 我已经看到它写在一些你不应该继承 UIButton 的地方。如果没有,我将如何更改我的所有按钮以在不复制大量代码的情况下具有此渐变?

提前致谢。

4

1 回答 1

3

编辑1:误读了有关图像的部分。您应该能够使用渐变将按钮状态本地设置为图像

// your code for setting up the gradient layer comes first
UIGraphicsBeginImageContext(CGSizeMake(1, [self bounds].size.height));
[gradientLayer renderInContext: UIGraphicsGetCurrentContext()];
UIImage *bgImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setBackGroundImage:bgImage forState:UIControlStateWhatever] // replace with correct states

==============================

我建议将您的初始化代码放在一个函数中awakeFromNib(对于按钮实际上没有在笔尖中使用但可能在代码中创建的情况)。您应该创建一个自定义初始化函数并在两者中调用它,initWithCoder这个initWithFrame 答案显示了一个很好的模式。

您可以通过调用在初始化中设置不同状态的背景

[self setBackGroundImage: forState];

在这种情况下,您的状态将在哪里UIControlStateHighlighted

除此之外,在这种情况下反对子类化的一个论点是,您实际上并没有定义任何自定义行为,您只是试图重用一些样式代码。这里不需要子类,您可以做一些简单的事情,例如在某处(可能在您的视图控制器中,或在另一个类中的某个函数中)创建一个格式化函数,该函数将 UIButton 作为场景并在其上执行所有初始化代码。这样,您就不会将按钮锁定在子类中(如果您实际上最终使用另一个 UIButton 子类,这很有用。例如,我喜欢使用一个定义自定义触摸行为的按钮,允许按钮为非矩形形状(并使其触摸区域受到限制)。

我看到的另一个论点是 UIButton 包含一些工厂函数,它们可能返回与您的子类不同类型的按钮,但如果您不使用这些函数,您可能永远不会遇到这个问题。

于 2012-06-25T14:46:15.703 回答