【问题标题】:iOS - Sub classed UIButton - Where to add code for highlighted state?iOS - 子类 UIButton - 在哪里为突出显示状态添加代码?
【发布时间】:2012-06-25 22:58:00
【问题描述】:

我希望我的 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 的地方。如果没有,我如何在不重复大量代码的情况下更改所有按钮以具有此渐变?

提前致谢。

【问题讨论】:

    标签: iphone ios uibutton


    【解决方案1】:

    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 以外的函数中(对于按钮实际上没有在笔尖中使用但可能在代码中创建的情况)。您应该创建一个自定义初始化函数并在initWithCoderinitWithFrame 中调用它This answer 显示了这样做的一个很好的模式。

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

    [self setBackGroundImage: forState];
    

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 2012-04-17
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      相关资源
      最近更新 更多