在我的应用程序的某些时候,我有一个突出显示的UIButton(例如当用户有他的手指在按钮上),我需要改变背景颜色,而按钮是突出显示的(所以当用户的手指仍然在按钮上)。

我尝试了以下方法:

_button.backgroundColor = [UIColor redColor];

但这并不奏效。颜色保持不变。当按钮没有高亮显示时,我尝试了同一段代码,它工作得很好。我还尝试在改变颜色后调用-setNeedsDisplay,它没有任何效果。

如何强制按钮改变背景颜色?


当前回答

一个更紧凑的解决方案(基于@aleksejs-mjaliks的答案):

Swift +四分之三的:

override var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? .lightGray : .white
    }
}

斯威夫特2:

override var highlighted: Bool {
    didSet {
        backgroundColor = highlighted ? UIColor.lightGrayColor() : UIColor.whiteColor()
    }
}

如果你不想覆盖,这是一个更新版本的@timur-bernikowich的答案(Swift 4.2):

extension UIButton {
  func setBackgroundColor(_ color: UIColor, forState controlState: UIControl.State) {
    let colorImage = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { _ in
      color.setFill()
      UIBezierPath(rect: CGRect(x: 0, y: 0, width: 1, height: 1)).fill()
    }
    setBackgroundImage(colorImage, for: controlState)
  }
}

其他回答

细节

Xcode 11.1 (11A1027), Swift 5

解决方案

import UIKit

extension UIColor {
    func createOnePixelImage() -> UIImage? {
        let size = CGSize(width: 1, height: 1)
        UIGraphicsBeginImageContext(size)
        defer { UIGraphicsEndImageContext() }
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.setFillColor(cgColor)
        context.fill(CGRect(origin: .zero, size: size))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

extension UIButton {
    func setBackground(_ color: UIColor, for state: UIControl.State) {
        setBackgroundImage(color.createOnePixelImage(), for: state)
    }
}

使用

button.setBackground(.green, for: .normal)

更新:

使用UIButtonBackgroundColor Swift库。

OLD:

使用下面的帮助工具创建一个1px x 1px的图像,灰度填充颜色:

UIImage *image = ACUTilingImageGray(248/255.0, 1);

或RGB填充颜色:

UIImage *image = ACUTilingImageRGB(253/255.0, 123/255.0, 43/255.0, 1);

然后,使用该图像设置按钮的背景图像:

[button setBackgroundImage:image forState:UIControlStateNormal];

助手

#pragma mark - Helpers

UIImage *ACUTilingImageGray(CGFloat gray, CGFloat alpha)
{
    return ACUTilingImage(alpha, ^(CGContextRef context) {
        CGContextSetGrayFillColor(context, gray, alpha);
    });
}

UIImage *ACUTilingImageRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
{
    return ACUTilingImage(alpha, ^(CGContextRef context) {
        CGContextSetRGBFillColor(context, red, green, blue, alpha);
    });
}

UIImage *ACUTilingImage(CGFloat alpha, void (^setFillColor)(CGContextRef context))
{
    CGRect rect = CGRectMake(0, 0, 0.5, 0.5);
    UIGraphicsBeginImageContextWithOptions(rect.size, alpha == 1, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    setFillColor(context);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

注意:ACU是我的Cocoa Touch静态库称为Acani Utilities的类前缀,其中AC是Acani, U是Utilities。

简单的是只使用UIButton扩展

extension UIButton {

    func setBackgroundColor(color: UIColor, forState: UIControl.State) {
        self.clipsToBounds = true  // add this to maintain corner radius
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(color.cgColor)
            context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            self.setBackgroundImage(colorImage, for: forState)
        }
    }

}

然后用这个

 optionButton.setBackgroundColor(color: UIColor(red:0.09, green:0.42, blue:0.82, alpha:1.0), forState: .selected)

 optionButton.setBackgroundColor(color: UIColor(red:0.96, green:0.96, blue:0.96, alpha:1.0), forState: .highlighted)

 optionButton.setBackgroundColor(color: UIColor(red:0.96, green:0.96, blue:0.96, alpha:1.0), forState: .normal)

解决方案Swift 3+没有子类化。

extension UIButton {
  func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    color.setFill()
    UIRectFill(rect)
    let colorImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    setBackgroundImage(colorImage, for: state)
  }
}

有了这个扩展,它很容易管理不同状态的颜色,它会自动褪色你的正常颜色,如果高亮的颜色是不提供的。

button.setBackgroundColor(.red, for: .normal)
class CustomButton: UIButton {

    override var isHighlighted: Bool {
        didSet {
            if (isHighlighted) {
                alpha = 0.5
            }
            else {
                alpha = 1
            }            
        }
    }

}