How to change the background color of a UIButton w

2019-01-01 09:53发布

At some point in my app I have a highlighted UIButton (for example when a user has his finger on the button) and I need to change the background color while the button is highlighted (so while the finger of the user is still on the button).

I tried the following:

_button.backgroundColor = [UIColor redColor];

But it is not working. The color remains the same. I tried the same piece of code when the button is not highlighted and it works fine. I also tried calling -setNeedsDisplay after changing the color, it didn't have any effect.

How to force the button to change the background color?

26条回答
千与千寻千般痛.
2楼-- · 2019-01-01 10:31

To solve this problem I created a Category to handle backgroundColor States with UIButtons:
ButtonBackgroundColor-iOS

You can install the category as a pod.

Easy to use with Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

[self.myButton bbc_backgroundColorNormal:[UIColor redColor]
                 backgroundColorSelected:[UIColor blueColor]];

Even more easy to use with Swift:

import ButtonBackgroundColor

...

let myButton:UIButton = UIButton(type:.Custom)

myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())

I recommend you import the pod with:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Using use_frameworks! in your Podfile makes easier to use your pods with Swift and objective-C.

IMPORTANT

I also wrote a Blog Post with more information.

查看更多
梦醉为红颜
3楼-- · 2019-01-01 10:32

An handy generic extension in Swift:

extension UIButton {
    private func imageWithColor(color: UIColor) -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

    func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
        self.setBackgroundImage(imageWithColor(color), forState: state)
    }
}

Swift 3.0

extension UIButton {
    private func imageWithColor(color: UIColor) -> UIImage? {
        let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        context?.setFillColor(color.cgColor)
        context?.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

    func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
        self.setBackgroundImage(imageWithColor(color: color), for: state)
    }
}
查看更多
余生无你
4楼-- · 2019-01-01 10:32

Use https://github.com/swordray/UIButtonSetBackgroundColorForState

Add to Podfile using CocoaPods

pod "UIButtonSetBackgroundColorForState"

Swift

button.setBackgroundColor(.red, forState: .highlighted)

Objective-C

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
查看更多
怪性笑人.
5楼-- · 2019-01-01 10:35

Here is the code in Swift to select for button state:

func imageWithColor(color:UIColor) -> UIImage {
    let rect:CGRect = CGRectMake(0.0, 0.0, 1.0, 1.0)
     UIGraphicsBeginImageContext(rect.size)
    let context:CGContextRef = UIGraphicsGetCurrentContext()!
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextFillRect(context, rect)
    let image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
    return image;
}

Example:

    self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)
查看更多
余生请多指教
6楼-- · 2019-01-01 10:36

Here's an approach in Swift, using a UIButton extension to add an IBInspectable, called highlightedBackgroundColor. Similar to subclassing, without requiring a subclass.

private var HighlightedBackgroundColorKey = 0
private var NormalBackgroundColorKey = 0

extension UIButton {

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &HighlightedBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &HighlightedBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    private var normalBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &NormalBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &NormalBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    override public var backgroundColor: UIColor? {
        didSet {
            if !highlighted {
                normalBackgroundColor = backgroundColor
            }
        }
    }

    override public var highlighted: Bool {
        didSet {
            if let highlightedBackgroundColor = self.highlightedBackgroundColor {
                if highlighted {
                    backgroundColor = highlightedBackgroundColor
                } else {
                    backgroundColor = normalBackgroundColor
                }
            }
        }
    }
}

I hope this helps.

查看更多
余欢
7楼-- · 2019-01-01 10:37

In Swift you can override the accessor of the highlighted (or selected) property rather than overriding the setHighlighted method

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }
查看更多
登录 后发表回答