突出显示时更改 UIButton 的背景颜色

Posted

技术标签:

【中文标题】突出显示时更改 UIButton 的背景颜色【英文标题】:Change background color of UIButton when Highlighted 【发布时间】:2010-10-26 10:26:33 【问题描述】:

您好,我想更改用户点击按钮的 UIButton 背景颜色。

我正在使用渐变显示背景颜色,当用户点击时我需要更改渐变颜色。

[btn setTitle: @"Next" forState:UIControlStateNormal];
CAGradientLayer *gradient = [CAGradientLayer layer];            
gradient.frame = btn.bounds;
gradient.cornerRadius = 10.0f;
locations = [[NSArray alloc] initWithObjects: 0.0f, 0.0f, 0.0f,0.0f, nil]; 
[gradient setLocations:locations];
colorNext = [[NSArray alloc] initWithObjects:…., nil]; 
gradient.colors = colorNext;
[locations release];
[btn.layer insertSublayer:gradient atIndex:0];
btn.titleLabel.textColor = [UIColor blackColor];

【问题讨论】:

这个问题有很好的答案:***.com/questions/14523348/… 【参考方案1】:

不建议更改 UIButton 的内部层层次结构,因为它可能会在未来的 ios 更新中中断。此外,它可能会导致 Apple 拒绝您的申请。更好的解决方案是创建一个按钮子类。这是一个如何做的例子:

@interface MyButton : UIButton
@end

@implementation MyButton

- (id)initWithFrame:(CGRect)frame

    if (self = [super initWithFrame:frame])
    
        [self addObserver:self forKeyPath:@"highlighted" options:NSKeyValueObservingOptionNew context:NULL];
    

    return self;


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

    [self setNeedsDisplay];


- (void)drawRect:(CGRect)rect

    [super drawRect:rect];

    if (self.highlighted == YES)
    
        CGContextRef ctx = UIGraphicsGetCurrentContext();

        CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

        const CGFloat *topGradientColorComponents = CGColorGetComponents([UIColor whiteColor].CGColor);
        const CGFloat *bottomGradientColorComponents = CGColorGetComponents([UIColor blackColor].CGColor);

        CGFloat colors[] =
        
            topGradientColorComponents[0], topGradientColorComponents[1], topGradientColorComponents[2], topGradientColorComponents[3],
            bottomGradientColorComponents[0], bottomGradientColorComponents[1], bottomGradientColorComponents[2], bottomGradientColorComponents[3]
        ;
        CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors) / (sizeof(colors[0]) * 4));
        CGColorSpaceRelease(rgb);

        CGContextDrawLinearGradient(ctx, gradient, CGPointMake(0, 0), CGPointMake(0, self.bounds.size.height), 0);
        CGGradientRelease(gradient);
    
    else
    
        // Do custom drawing for normal state
    


- (void)dealloc

    [self removeObserver:self forKeyPath:@"highlighted"];

    [super dealloc];


@end

您可能需要对其进行一些修改以使其执行您想要的操作,但我认为您已了解基本概念。

【讨论】:

你能告诉我在“//为突出显示的状态做自定义绘图”中需要做什么吗?和我之前做的一样吗 我添加了一个关于如何绘制渐变的示例。如果你想做其他自定义绘图,你应该看看 Quartz 2D Programming Guide。 非常感谢,我会试试的:) 我会说,如果您从情节提要/IB 实现按钮,您应该在 -(void)awakeFromNib 中添加观察者,因为 initWithFrame 永远不会被调用。无论如何,谢谢你的回答! 你为什么说Apple可能会拒绝你的应用程序使用-insertSublayer:atIndex:?我在 UIButton、UIView 或 CALayer 的文档中没有看到任何建议该方法已被弃用的信息。在 UIView“子类化的替代方案”下,它说:“动画是对视图进行可见更改的另一种方式,而无需您子类化和实现复杂的绘图代码。”【参考方案2】:

试试这个:

[Button addTarget:self action:@selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
[Button addTarget:self action:@selector(setBgColorForButton:) forControlEvents:UIControlEventTouchDown];
[Button addTarget:self action:@selector(clearBgColorForButton:) forControlEvents:UIControlEventTouchDragExit];

-(void)setBgColorForButton:(UIButton*)sender

    [sender setBackgroundColor:[UIColor blackColor]];


-(void)clearBgColorForButton:(UIButton*)sender

    [sender setBackgroundColor:[UIColor redColor]];


-(void)doSomething:(UIButton*)sender

double delayInSeconds = 0.3;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
        [sender setBackgroundColor:[UIColor redColor]];
    );
    //do something


【讨论】:

谢谢!这对我有用,不需要子类化按钮。好主意! 实际上,有一个问题 - 当用户点击按钮并将触摸移出按钮时 - 按钮仍然突出显示,但这可以通过事件 ...DragExit 轻松解决。 谢谢。非常简单的解决方案。其他人都在想这个。 谢谢。但对我来说,只有当我在模拟器中留下“点击”时,突出显示的状态才会被激活。实际设备中的行为是否不同?或者即使在模拟器中也可以使用?【参考方案3】:

您可以使用此方法创建指定颜色的实体 UIImage,然后将其应用于您的按钮。我已经为 UIImage 创建了一个类别来执行此操作。

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size

    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, (CGRect).size = size);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;


+ (UIImage *)imageWithColor:(UIColor *)color

    return [UIImage imageWithColor:color size:CGSizeMake(1, 1)];

用法:

[button setBackgroundImage:[UIImage imageWithColor:[UIColor redColor]]
                  forState:UIControlStateNormal];

正如Matthias 指出的那样,您可以安全地使用 1x1 图像作为按钮背景——它将被拉伸以填充按钮。

【讨论】:

感谢您的想法。不过,我用直接绘制上下文替换了 UIView 渲染。例如:CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillRect(context, CGRectMake(0, 0, 1, 1));(我使用 1,1 作为尺寸,因为我创建了一个 1x1 的图像。UIButton 将拉伸图像。) 是的,CGContextSetFillColorWithColor 好多了! 这可能是迄今为止最好的解决方案:D 从我的角度来看,您的解决方案是最好的并且更易于实施。恭喜。 这适用于圆角。只需设置button.clipsToBounds = YES;【参考方案4】:

我在 GitHub 上找到了这个 AYUIButton,它运行良好 :) 这是示例代码:

[btn setBackgroundColor:[UIColor redColor] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor blueColor] forState:UIControlStateHighlighted];

【讨论】:

【参考方案5】:

当您设置按钮的 TintColor 时,它会在突出显示时起作用

[YourButton setTintColor:[UIColor color]];

【讨论】:

您需要做什么以及您的问题是什么?如果您需要帮助,请发布一些代码@Vidhi 您检查过其他答案了吗? UIButton 被点击/突出显示时,我想改变它的背景颜色。我试过你的代码,但它没有改变背景颜色。因此我最终得到了解决方案[btnSubmit addTarget:self action:@selector(backgroundwhite:) forControlEvents:UIControlEventTouchDown]; -(void)backgroundwhite:(id)sender [sender setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [sender setBackgroundColor:[UIColor whiteColor]]; 【参考方案6】:

斯威夫特

UIButton 扩展,可让您为每个状态指定背景颜色:

https://github.com/acani/UIButtonBackgroundColor

请注意,对于 iphone 6 plus,您应该在 .swift 类的扩展名中更改以下内容,这将为所有版本修复:

//let rect = CGRect(x: 0, y: 0, width: 0.5, height: 0.5) comment this line
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)

【讨论】:

以上是关于突出显示时更改 UIButton 的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift (tvOS) 中,如何更改 UIButton 的突出显示和焦点颜色?

在 Swift 3 中突出显示(或点击)按钮时如何更改 UIButton 边框颜色?

Objective C - UIButton 保持突出显示/选中,背景颜色和字体颜色在突出显示/选中时发生变化

突出显示/选定状态问题的 UIButton 背景颜色

UIButton 背景颜色与突出显示的文本重叠

如何在滚动时突出显示/更改表格视图部分标题的背景颜色