首页 文章

如何突出显示UIButton的背景颜色?

提问于
浏览
207

在我的应用程序中的某个时刻,我有一个突出显示的 UIButton (例如,当用户将手指放在按钮上时)我需要在按钮突出显示时更改背景颜色(因此,当用户的手指仍在按钮上时) ) .

我尝试了以下方法:

_button.backgroundColor = [UIColor redColor];

但它没有用 . 颜色保持不变 . 当按钮没有突出显示时我尝试了相同的代码,它工作正常 . 我也尝试在改变颜色后调用 -setNeedsDisplay ,它没有任何效果 .

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

27 回答

  • 1

    你可以覆盖 UIButtonsetHighlighted 方法 .

    Objective-C

    - (void)setHighlighted:(BOOL)highlighted {
        [super setHighlighted:highlighted];
    
        if (highlighted) {
            self.backgroundColor = UIColorFromRGB(0x387038);
        } else {
            self.backgroundColor = UIColorFromRGB(0x5bb75b);
        }
    }
    

    Swift 3.0 and Swift 4.1

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

    斯威夫特3:

    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, forUIControlState state: UIControlState) {
            self.setBackgroundImage(imageWithColor(color: color), for: state)
        }
    }
    
  • 0

    可以通过XIB设置它 . 在xib中设置突出显示的色调,同时点击按钮 . 因为直到现在还没有以编程方式正确的方法 . 因此,通过在XIB中设置它很容易 .

    它会工作正常:)享受..

  • 45

    不确定这种解决方案是否解决了您的问题,或者是否符合您的一般开发前景,但我要尝试的第一件事就是更改touchDown事件上按钮的背景颜色 .

    Option 1:

    您需要捕获两个事件,当用户按下按钮时,UIControlEventTouchDown将用于捕获 . UIControlEventTouchUpInside和UIControlEventTouchUpOutside将在他们释放按钮时将其恢复到正常状态

    UIButton *myButton =  [UIButton buttonWithType:UIButtonTypeCustom];
    [myButton setFrame:CGRectMake(10.0f, 10.0f, 100.0f, 20.f)];
    [myButton setBackgroundColor:[UIColor blueColor]];
    [myButton setTitle:@"click me:" forState:UIControlStateNormal];
    [myButton setTitle:@"changed" forState:UIControlStateHighlighted];
    [myButton addTarget:self action:@selector(buttonHighlight:) forControlEvents:UIControlEventTouchDown];
    [myButton addTarget:self action:@selector(buttonNormal:) forControlEvents:UIControlEventTouchUpInside];
    

    Option 2:

    返回由您想要的高光颜色制作的图像 . 这也可以是一个类别 .

    + (UIImage *)imageWithColor:(UIColor *)color {
       CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
       UIGraphicsBeginImageContext(rect.size);
       CGContextRef context = UIGraphicsGetCurrentContext();
    
       CGContextSetFillColorWithColor(context, [color CGColor]);
       CGContextFillRect(context, rect);
    
       UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
    
       return image;
    }
    

    然后更改按钮的突出显示状态:

    [myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];
    
  • 21

    无需将 highlighted 覆盖为计算属性 . 您可以使用属性观察器来触发背景颜色更改:

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

    Swift 4

    override open var isHighlighted: Bool {
        didSet {
            backgroundColor = isHighlighted ? UIColor.lightGray : UIColor.white
        }
    }
    
  • 0

    在Swift中,您可以覆盖突出显示(或选定)属性的访问者,而不是覆盖setHighlighted方法

    override var highlighted: Bool {
            get {
                return super.highlighted
            }
            set {
                if newValue {
                    backgroundColor = UIColor.blackColor()
                }
                else {
                    backgroundColor = UIColor.whiteColor()
                }
                super.highlighted = newValue
            }
        }
    
  • 2

    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)
        }
    }
    
  • 2

    覆盖突出显示的变量 . 添加 @IBInspectable 可以让你在故事板中编辑突出显示的backgroundColor,这也很精彩 .

    class BackgroundHighlightedButton: UIButton {
        @IBInspectable var highlightedBackgroundColor :UIColor?
        @IBInspectable var nonHighlightedBackgroundColor :UIColor?
        override var highlighted :Bool {
            get {
                return super.highlighted
            }
            set {
                if newValue {
                    self.backgroundColor = highlightedBackgroundColor
                }
                else {
                    self.backgroundColor = nonHighlightedBackgroundColor
                }
                super.highlighted = newValue
            }
        }
    }
    
  • 1

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

    Swift 3/4+

    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)
      }
    }
    
  • 360

    使用 Swift 3+ 语法的UIButton扩展:

    extension UIButton {
        func setBackgroundColor(color: UIColor, forState: UIControlState) {
            UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
            UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
            UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            self.setBackgroundImage(colorImage, for: forState)
        }}
    

    使用它像:

    YourButton.setBackgroundColor(color: UIColor.white, forState: .highlighted)
    

    原答案:https://stackoverflow.com/a/30604658/3659227

  • 9

    您可以使用此类别添加方法 setBackgroundColor:forState:

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

  • 293

    这是Swift中的一种方法,使用UIButton扩展来添加IBInspectable,名为highlightedBackgroundColor . 与子类化类似,不需要子类 .

    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
                    }
                }
            }
        }
    }
    

    我希望这有帮助 .

  • 9

    我没有子类化的最佳解决方案 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)
    
  • 1

    更新:

    使用UIButtonBackgroundColor Swift库 .

    旧:

    使用下面的帮助程序创建一个带有灰度填充颜色的1 px x 1 px图像:

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

    或RGB填充颜色:

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

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

    [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 .

  • 4

    试试这个 !!!!

    对于TouchedDown事件集,一种颜色和TouchUpInside设置另一种颜色 .

    - (IBAction)touchedDown:(id)sender {
        NSLog(@"Touched Down");
        btn1.backgroundColor=[UIColor redColor];
    }
    
    - (IBAction)touchUpInside:(id)sender {
        NSLog(@"TouchUpInside");
        btn1.backgroundColor=[UIColor whiteColor];    
    }
    
  • 6

    对UIButton进行子类化并添加可检查的属性以方便使用(用Swift 3.0编写):

    final class SelectableBackgroundButton: UIButton {
    
        private struct Constants {
            static let animationDuration: NSTimeInterval = 0.1
        }
    
        @IBInspectable
        var animatedColorChange: Bool = true
    
        @IBInspectable
        var selectedBgColor: UIColor = UIColor.blackColor().colorWithAlphaComponent(0.2)
    
        @IBInspectable
        var normalBgColor: UIColor = UIColor.clearColor()
    
        override var selected: Bool {
            didSet {
                if animatedColorChange {
                    UIView.animateWithDuration(Constants.animationDuration) {
                        self.backgroundColor = self.selected ? self.selectedBgColor : self.normalBgColor
                    }
                } else {
                    self.backgroundColor = selected ? selectedBgColor : normalBgColor
                }
            }
        }
    
        override var highlighted: Bool {
            didSet {
                if animatedColorChange {
                    UIView.animateWithDuration(Constants.animationDuration) {
                        self.backgroundColor = self.highlighted ? self.selectedBgColor : self.normalBgColor
                    }
                } else {
                    self.backgroundColor = highlighted ? selectedBgColor : normalBgColor
                }
            }
        }
    }
    
  • -4

    如果您有图像,请尝试此操作:

    -(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
    

    或者看看 showsTouchWhenHighlighted 是否足够你 .

  • 4

    您可以继承UIButton并创建一个很好的forState .

    colourButton.h

    #import <UIKit/UIKit.h>
    
    @interface colourButton : UIButton
    
    -(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;
    
    @end
    

    colourButton.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
    

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

    我已经使用NSMutableDictionay为每个状态存储UIColor,我必须为Key做一个令人讨厌的文本转换,因为UIControlState不是一个很好的直接Int . 如果你可以在那里使用那么多对象初始化一个数组并使用State作为索引 .

    因此,许多人遇到困难,例如选中和禁用按钮,需要更多逻辑 .

    另一个问题是,如果你尝试同时设置多种颜色,我没有试过按钮,但如果你能做到这一点,它可能无法正常工作

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

    我假设这是StoryBoard,没有init,initWithFrame所以如果你需要它们就添加它们 .

  • 2

    我开源了一个UIButton子类,STAButton,填补这个有缺口的功能漏洞 . 可在MIT许可下使用 . 适用于iOS 7(我没有使用较旧的iOS版本进行测试) .

  • 4

    为了解决这个问题,我创建了一个类别来处理带有 UIButtonsbackgroundColor 状态:
    ButtonBackgroundColor-iOS

    您可以将类别安装为pod .

    易于使用 Objective-C

    @property (nonatomic, strong) UIButton *myButton;
    
    ...
    
    [self.myButton bbc_backgroundColorNormal:[UIColor redColor]
                     backgroundColorSelected:[UIColor blueColor]];
    

    更容易使用 Swift

    import ButtonBackgroundColor
    
    ...
    
    let myButton:UIButton = UIButton(type:.Custom)
    
    myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())
    

    我建议你导入pod:

    platform :ios, '8.0'
    use_frameworks!
    
    pod 'ButtonBackgroundColor', '~> 1.0'
    

    使用use_frameworks!在你的Podfile中使用Swift和objective-C更容易使用你的pod .

    IMPORTANT

    I also wrote a Blog Post with more information.

  • 86

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

    使用CocoaPods添加到Podfile

    pod "UIButtonSetBackgroundColorForState"
    

    Swift

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

    Objective-C

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

    试试 tintColor

    _button.tintColor = [UIColor redColor];
    
  • 2

    以下是Swift中用于选择按钮状态的代码:

    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;
    }
    

    例:

    self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)
    
  • 1

    把它放进去你很高兴:
    *可以在IB中设置proerty,如果没有设置突出显示的背景,按下时背景不会改变

    private var highlightedBackgroundColors = [UIButton:UIColor]()
    private var unhighlightedBackgroundColors = [UIButton:UIColor]()
    extension UIButton {
    
        @IBInspectable var highlightedBackgroundColor: UIColor? {
            get {
                return highlightedBackgroundColors[self]
            }
    
            set {
                highlightedBackgroundColors[self] = newValue
            }
        }
    
        override open var backgroundColor: UIColor? {
            get {
                return super.backgroundColor
            }
    
            set {
                unhighlightedBackgroundColors[self] = newValue
                super.backgroundColor = newValue
            }
        }
    
        override open var isHighlighted: Bool {
            get {
                return super.isHighlighted
            }
    
            set {
                if highlightedBackgroundColor != nil {
                    super.backgroundColor = newValue ? highlightedBackgroundColor : unhighlightedBackgroundColors[self]
                }
                super.isHighlighted = newValue
            }
        }
    }
    
  • 12

    低于 UIIImage 扩展名将生成具有指定颜色参数的图像对象 .

    extension UIImage {
        static func imageWithColor(tintColor: UIColor) -> UIImage {
            let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
            UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
            tintColor.setFill()
            UIRectFill(rect)
            let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return image
           }
        }
    

    按钮的示例用法可以应用于按钮对象,如下所示:

    setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 232/255, green: 130/255, blue: 121/255, alpha: 1.0)), for: UIControlState.highlighted)
    
    setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 255/255, green: 194/255, blue: 190/255, alpha: 1.0)), for: UIControlState.normal)
    
  • 16
    class CustomButton: UIButton {
    
        override var isHighlighted: Bool {
            didSet {
                if (isHighlighted) {
                    alpha = 0.5
                }
                else {
                    alpha = 1
                }            
            }
        }
    
    }
    
  • 40

    如果你不会覆盖只设置两个动作touchDown touchUpInside

相关问题