iOS - 子类UIButton - 在哪里添加突出显示状态的代码?

时间:2012-06-25 13:29:34

标签: iphone ios uibutton

我希望我的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的子类。如果没有,我如何更改所有按钮以获得此渐变而不重复大量代码?

提前致谢。

1 个答案:

答案 0 :(得分:3)

edit1:误读了有关图片的部分。 您应该可以使用渐变

将此按钮状态设置为图像
// 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以外的函数中(对于按钮实际上没有在nib中使用但可能在代码中创建的情况)。您应该创建一个自定义初始化函数,并在initWithCoderinitWithFrame This answer中调用它,这样做会显示出相当不错的模式。

您可以通过调用

为初始化中的不同状态设置背景
[self setBackGroundImage: forState];

在这种情况下,您的州将是UIControlStateHighlighted

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

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