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

我尝试了以下方法:

_button.backgroundColor = [UIColor redColor];

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

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


当前回答

你可以子类化UIButton并创建forState。

colourButton.h

#import <UIKit/UIKit.h>

@interface colourButton : UIButton

-(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;

@end

颜色按钮.m

#import "colourButton.h"

@implementation colourButton
{
    NSMutableDictionary *colours;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    // If colours does not exist
    if(!colours)
    {
        colours = [NSMutableDictionary new];  // The dictionary is used to store the colour, the key is a text version of the ENUM
        colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]] = (UIColor*)self.backgroundColor;  // Store the original background colour
    }

    return self;
}

-(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state
{
    // If it is normal then set the standard background here
    if(state & UIControlStateNormal)
    {
        [super setBackgroundColor:backgroundColor];
    }

    // Store the background colour for that state
    colours[[NSString stringWithFormat:@"%lu", state]]= backgroundColor;
}

-(void)setHighlighted:(BOOL)highlighted
{
    // Do original Highlight
    [super setHighlighted:highlighted];

    // Highlight with new colour OR replace with orignial
    if (highlighted && colours[[NSString stringWithFormat:@"%lu", UIControlStateHighlighted]])
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateHighlighted]];
    }
    else
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]];
    }
}

-(void)setSelected:(BOOL)selected
{
    // Do original Selected
    [super setSelected:selected];

    // Select with new colour OR replace with orignial
    if (selected && colours[[NSString stringWithFormat:@"%lu", UIControlStateSelected]])
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateSelected]];
    }
    else
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]];
    }
}

@end

注释(这是一个例子,我知道有问题,这里有一些)

我已经使用了一个NSMutableDictionay来存储每个状态的UIColor,我必须为键做一个讨厌的文本转换,因为UIControlState不是一个很好的直Int。如果它在哪里,你可以init一个数组与许多对象,并使用状态作为一个索引。

因此,你有很多困难,例如一个选中&禁用按钮,一些更多的逻辑是需要的。

另一个问题是,如果你试图同时设置多种颜色,我没有尝试过一个按钮,但如果你能这样做,它可能不会工作

 [btn setBackgroundColor:colour forState:UIControlStateSelected & UIControlStateHighlighted];

我假设这是StoryBoard,没有init和initWithFrame如果你需要,可以添加它们。

其他回答

你可以重写UIButton的setHighlighted方法。

objective - c

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];

    if (highlighted) {
        self.backgroundColor = UIColorFromRGB(0x387038);
    } else {
        self.backgroundColor = UIColorFromRGB(0x5bb75b);
    }
}

Swift 3.0和Swift 4.1

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.black : UIColor.white
    }
}

使用https://github.com/swordray/UIButtonSetBackgroundColorForState

使用CocoaPods添加到Podfile

pod "UIButtonSetBackgroundColorForState"

斯威夫特

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

objective - c

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];

细节

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)

在Swift 5中

对于那些不想使用彩色背景击败所选状态的人

简单地说,你可以通过使用#Selector & if语句轻松地为每个状态单独更改UIButton颜色来解决这个问题

例如:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.myButtonOutlet.backgroundColor = UIColor.white  //to reset the button color to its original color ( optionally )
}

@IBOutlet weak var myButtonOutlet: UIButton!{
    didSet{  // Button selector and image here
        self.myButtonOutlet.setImage(UIImage(systemName: ""), for: UIControl.State.normal)

        self.myButtonOutlet.setImage(UIImage(systemName: "checkmark"), for: UIControl.State.selected)



        self.myButtonOutlet.addTarget(self, action: #selector(tappedButton), for: UIControl.Event.touchUpInside)
    }
}

@objc func tappedButton() {  // Colors selection is here
    if self.myButtonOutlet.isSelected == true {

        self.myButtonOutlet.isSelected = false
        self.myButtonOutlet.backgroundColor = UIColor.white         
    } else {
        self.myButtonOutlet.isSelected = true

        self.myButtonOutlet.backgroundColor = UIColor.black
        self.myButtonOutlet.tintColor00 = UIColor.white

    }
}

你可以使用这个类别添加方法setBackgroundColor:forState:

https://github.com/damienromito/UIButton-setBackgroundColor-forState-