【问题标题】:How to change the background color of a UIButton while it's highlighted?突出显示时如何更改 UIButton 的背景颜色?
【发布时间】:2013-01-09 12:11:23
【问题描述】:

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

我尝试了以下方法:

_button.backgroundColor = [UIColor redColor];

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

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

【问题讨论】:

标签: ios objective-c xcode uibutton


【解决方案1】:

试试tintColor:

_button.tintColor = [UIColor redColor];

【讨论】:

  • 您确定它在 IB 中已链接吗?如果你这样做NSLog(@"%@", _button);,你会得到什么?
  • 如果您使用的是UIButtonTypeCustom,这将不起作用。
【解决方案2】:

如果你有图片试试这个:

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

或者看看showsTouchWhenHighlighted对你来说够不够用。

【讨论】:

  • 我尝试过使用showsTouchWhenHighlighted,但没有帮助。我不想使用 setBackgroundImage:forState:。我实际上是在尝试使用 backgroundColor 来不使用任何图像。
【解决方案3】:

不确定这种方法是否能解决您所追求的问题,或者是否适合您的一般开发环境,但我会尝试的第一件事是更改 touchDown 事件按钮的背景颜色。

选项 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];

选项 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];

【讨论】:

  • 将 UIControlEventTouchUpOutside 和 UIControlEventTouchCancel 添加到 buttonHighlight: 事件列表,它会一直工作。
  • 选项二是迄今为止我发现的最好的。不过,我想故事板在这种情况下确实有其优势!
  • Thomas 的回答更好,我也用这个
  • 如果您使用 layer.cornerRadius 并使用选项 #2,则需要确保将 clipsToBounds 设置为 true 以使图像的角也变圆。
  • 如果有人过来并需要 Swift 的答案:stackoverflow.com/questions/26600980/…
【解决方案4】:

您可以覆盖UIButtonsetHighlighted 方法。

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

【讨论】:

  • 只是一个新手问题,你会在哪里子类化按钮方法?如果我在名为 ConversionViewController 的视图控制器中有一个按钮,我将如何设置该按钮以在突出显示或点击时更改背景颜色?我会继承 COnversionViewController 中的 setHIghlighted 吗?
  • @YakivKovalskiy 假设您使用的是子类,您可以添加两个 UIColor 属性,例如normalBackground 和 highlightBackground,然后相应地分配 self.backgroundColor = normalBackground 或 highlightBackground。不要忘记添加一个 init 方法以方便使用,例如initWithBackground:highlightedBackground:
  • 不错的解决方案,只有一个建议:backgroundColor = isHighlighted ? .lightGray : .white
  • 为什么没有人提到 setter 仅在您点击按钮时才被调用,而不是在初始布局期间!因此,默认情况下,在您触摸按钮之前没有颜色。因此,要使其正常工作,您还需要在开头某处显式调用isHighlighted = false(例如在初始化时)。
  • 所以,对于 Objective-C。我们必须继承 UIButton 来实现这个效果,对吧?
【解决方案5】:

更新:

使用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 是我的名为 Acani Utilities 的 Cocoa Touch 静态库的类前缀,其中 AC 代表 Acani,U 代表 Utilities。

【讨论】:

    【解决方案6】:

    在 Swift 中,您可以覆盖高亮(或选定)属性的访问器,而不是覆盖 setHighlighted 方法

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

    【讨论】:

    • 这完全可行,但我很困惑你是如何解决这个问题的?据我所知,这些参数不在文档或 UIButton.h 中。
    • 这是模拟目标 c 中覆盖 setHightlighted 行为的快速语法。在此处查看有关计算属性的文档developer.apple.com/library/ios/documentation/Swift/Conceptual/…
    • 在swift中你可以使用didSet
    • 我添加了财产观察者的例子:stackoverflow.com/a/29186375/195173.
    • 我想@shimizu 的问题是你怎么知道highlighted 是UIButton 上的一个属性。答案是它是 UIControl 上的一个属性,UIButton 继承自该属性。
    【解决方案7】:

    一个方便的 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)
        }
    }
    

    【讨论】:

      【解决方案8】:

      您可以将 UIButton 子类化并创建一个不错的 forState。

      colorButton.h

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

      colorButton.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,我必须对 Key 进行令人讨厌的文本转换,因为 UIControlState 不是一个很好的直接 Int。如果你可以用这么多对象初始化一个数组并使用状态作为索引。

      因此,你们很多人都遇到了困难,例如选择和禁用按钮,需要更多逻辑。

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

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

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

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

        • 不需要子类化的巨大优势。
        【解决方案10】:

        覆盖突出显示的变量。 添加@IBInspectable 可以让您在故事板中编辑突出显示的背景颜色,这也很漂亮。

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

        【讨论】:

          【解决方案11】:

          无需将highlighted 重写为计算属性。您可以使用属性观察器来触发背景颜色变化:

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

          斯威夫特 4

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

          【讨论】:

          • 我从未使用过这样的功能。你能解释一下这是怎么回事吗?是在 IBAction buttonPress 函数中还是在 viewDidLoad 中?
          • 如果我有多个不同颜色的 UIButton 怎么办?
          • @Dave G,您可以通过单击 File&gt;New&gt;File&gt;Cocoa Touch Class 并将其设置为 subclass of UIButton 创建 UIButton 的新子类。将文件命名为 ex CustomButton,这将成为文件名和类名。在这个文件中,放入上面显示的override var highlighted 代码。最后一步,设置 Interface Builder 上的 UIButton 使用这个 CustomButton 子类,方法是转到显示“自定义类”并有一个下拉框的属性页面。它会以灰色字母显示“UIButton”。下拉列表应显示 CustomButton。选择它,按钮现在是子类。
          • 为什么没有人提到 setter 仅在您点击按钮时才被调用,而不是在初始布局期间!因此默认情况下,在您触摸按钮之前没有颜色。
          • 因此,要使其正常工作,您还需要在开头某处显式调用isHighlighted = false(例如在初始化时)。
          【解决方案12】:

          试试这个!!!!

          为 TouchedDown 事件设置一种颜色,为 TouchUpInside 设置另一种颜色。

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

          【讨论】:

          • 为我工作。我只需要添加- (IBAction)onButtonTouchDragOutside:(UIButton *)sender { 以确保当用户不小心将手指从按钮上拖开时颜色不会保持不变。
          【解决方案13】:

          这是 Swift 中的一种方法,使用 UIButton 扩展来添加 IBInspectable,称为 highlightBackgroundColor。类似于子类化,不需要子类。

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

          我希望这会有所帮助。

          【讨论】:

          • 对于 swift 2.0,您需要更新对 objc_setAssociatedObject 的调用以使用枚举:objc_setAssociatedObject(self, &NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
          • 如果你想把它全部保存在 Storyboard 中,这绝对是 Swift 中最好的方法。
          • 我更喜欢使用子类而不是扩展,因为这会影响整个应用程序
          【解决方案14】:

          我已经开源了一个 UIButton 子类 STAButton,以填补这个巨大的功能漏洞。在 MIT 许可下可用。适用于 iOS 7+(我没有测试过旧的 iOS 版本)。

          【讨论】:

            【解决方案15】:

            这是 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)
            

            【讨论】:

              【解决方案16】:

              为了解决这个问题,我创建了一个类别来处理带有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。

              重要

              I also wrote a Blog Post with more information.

              【讨论】:

                【解决方案17】:

                更紧凑的解决方案(基于 @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)
                  }
                }
                

                【讨论】:

                • @FedericoZanetello 这将覆盖应用程序中所有按钮中的 isHighlighted,我认为这不是一个好的解决方案。我不同意帖木儿的回答。
                【解决方案18】:

                使用 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

                【讨论】:

                  【解决方案19】:

                  子类化 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
                              }
                          }
                      }
                  }
                  

                  【讨论】:

                    【解决方案20】:

                    如果你不覆盖 只需设置两个动作 接地 touchUpInside

                    【讨论】:

                      【解决方案21】:

                      放下它,你就可以开始了:
                      *在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
                              }
                          }
                      }
                      

                      【讨论】:

                        【解决方案22】:

                        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)
                        

                        【讨论】:

                          【解决方案23】:

                          斯威夫特 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)
                              }
                          }
                          

                          【讨论】:

                            【解决方案24】:

                            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)
                            

                            【讨论】:

                            • 很好,这在 Swift 5 中也很有效。
                            • 我非常感谢这个答案,因为它正是 API 所缺少的。它类似于现有的 setTitle(for:)。恕我直言,这应该是公认的答案。
                            【解决方案25】:
                            class CustomButton: UIButton {
                            
                                override var isHighlighted: Bool {
                                    didSet {
                                        if (isHighlighted) {
                                            alpha = 0.5
                                        }
                                        else {
                                            alpha = 1
                                        }            
                                    }
                                }
                            
                            }
                            

                            【讨论】:

                              【解决方案26】:

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

                              使用 CocoaPods 添加到 Podfile

                              pod "UIButtonSetBackgroundColorForState"
                              

                              斯威夫特

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

                              Objective-C

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

                              【讨论】:

                                【解决方案27】:
                                extension UIButton {
                                    func setBackgroundColor(color: UIColor, forState: UIControl.State) {
                                        let size = CGSize(width: 1, height: 1)
                                        UIGraphicsBeginImageContext(size)
                                        let context = UIGraphicsGetCurrentContext()
                                        context?.setFillColor(color.cgColor)
                                        context?.fill(CGRect(origin: CGPoint.zero, size: size))
                                        let colorImage = UIGraphicsGetImageFromCurrentImageContext()
                                        UIGraphicsEndImageContext()
                                        setBackgroundImage(colorImage, for: forState)
                                    }
                                
                                }
                                

                                Swift 5,感谢@Maverick

                                【讨论】:

                                  【解决方案28】:

                                  详情

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

                                  【讨论】:

                                    【解决方案29】:

                                    简单就是只使用那个 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)
                                    

                                    【讨论】:

                                      【解决方案30】:

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

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2021-11-04
                                        • 2013-12-16
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多