简体   繁体   English

如何在 Swift 中设置 UIButton 背景颜色 forState: UIControlState.Highlighted

[英]How do I set UIButton background color forState: UIControlState.Highlighted in Swift

I can set the background color for a button but I can't work out how to set the background color for UIControlState.Highlighted .我可以设置按钮的背景颜色,但我不知道如何设置UIControlState.Highlighted的背景颜色。 Is it even possible?甚至可能吗? or do I need to go down the setBackgroundImage path?还是我需要沿着setBackgroundImage路径走下去?

If anyone stops by, another way to go maybe more easily if it is something you need more than once... I wrote a short extension for UIButton, it works just fine:如果有人停下来,如果你不止一次需要它,那么另一种方式可能更容易......我为 UIButton 编写了一个简短的扩展,它工作得很好:

for Swift 3对于 Swift 3

extension UIButton {
    func setBackgroundColor(color: UIColor, forState: UIControlState) {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), color.CGColor)
        CGContextFillRect(UIGraphicsGetCurrentContext(), CGRect(x: 0, y: 0, width: 1, height: 1))
        let colorImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        self.setBackgroundImage(colorImage, forState: forState)
    }
}

for Swift 4对于 Swift 4

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

You use it just like setBackgroundImage :您可以像使用setBackgroundImage一样使用它:

yourButton.setBackgroundColor(color: UIColor.white, forState: UIControl.State.highlighted)

Syntax changes to @winterized extension for Swift 3+ syntax Swift 3+ 语法的@winterized 扩展的语法更改

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

Below will be one way to go.下面将是一种方法。 Two IBActions.两个 IBAction。 One to control background color when depressing a button, one on release.按下按钮时控制背景颜色,释放时控制背景颜色。

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var button: UIButton!

    @IBAction func buttonClicked(sender: AnyObject) { //Touch Up Inside action
        button.backgroundColor = UIColor.whiteColor()
    }

    @IBAction func buttonReleased(sender: AnyObject) { //Touch Down action
        button.backgroundColor = UIColor.blueColor()

    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }
}

When you look at the autocomplete options for your button after adding a period, you can set a background color, but not for specified state.添加句点后查看按钮的自动完成选项时,您可以设置背景颜色,但不能设置指定状态。 You can only set background images.您只能设置背景图像。 Now of course if you are married to doing it this way instead of using the method I show above, you could load an image of the desired color as the background image using the setbackgroundImageForState property.现在,当然,如果您愿意这样做而不是使用我上面展示的方法,您可以使用 setbackgroundImageForState 属性加载所需颜色的图像作为背景图像。

在此处输入图片说明

在此处输入图片说明

Swift 4+ compatibility for the accepted answer :已接受答案的 Swift 4+ 兼容性:

extension UIButton {

  /// Sets the background color to use for the specified button state.
  func setBackgroundColor(color: UIColor, forState: UIControlState) {

    let minimumSize: CGSize = CGSize(width: 1.0, height: 1.0)

    UIGraphicsBeginImageContext(minimumSize)

    if let context = UIGraphicsGetCurrentContext() {
      context.setFillColor(color.cgColor)
      context.fill(CGRect(origin: .zero, size: minimumSize))
    }

    let colorImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    self.clipsToBounds = true
    self.setBackgroundImage(colorImage, for: forState)
  }
}

Compatible SwiftLint and fix the bug of broken auto layout / corner radius.兼容 SwiftLint 并修复自动布局/圆角半径损坏的错误。

Swift 4 Version of this solution :此解决方案的Swift 4 版本:

extension UIButton {

    func setBackgroundColor(_ color: UIColor, for state: 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()

        setBackgroundImage(colorImage, for: state)
    }
}

Seems nobody here has mentioned using Key Value Observation yet, but it's another approach.似乎这里没有人提到使用Key Value Observation ,但这是另一种方法。

A reason for doing so instead of picking the other answers here is you don't need to go creating new images all the time nor be concerned with secondary effects of assigning images to buttons (eg cornerRadius effects).这样做而不是在这里选择其他答案的一个原因是您不需要一直创建新图像,也不需要关心将图像分配给按钮的次要效果(例如,cornerRadius 效果)。

But you'll need to create a class for the observer, who would be responsible for storing the different background colours and applying them in the observeValue() method.但是您需要为观察者创建一个类,该类负责存储不同的背景颜色并将它们应用到observeValue()方法中。

public class ButtonHighlighterObserver: NSObject {

  var observedButton:UIButton? = nil

  var backgroundColor: UIColor            = UIColor.white
  var backgroundHighlightColor: UIColor   = UIColor.gray

  public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

    // Perform background color changes when highlight state change is observed
    if keyPath == "highlighted", object as? UIButton === observedButton {
        observedButton!.backgroundColor = observedButton!.isHighlighted ? self.backgroundHighlightColor : self.backgroundColor
    }
}

} }

Then all you need to do is manage addObserver / removeObserver during operation:然后你需要做的就是在操作过程中管理 addObserver / removeObserver :

// Add observer to button's highlighted value
button.addObserver(anObserver, forKeyPath: "highlighted", options: [.new], context: nil)
anObserver.observedButton = button

// ...

// And at deinit time, be sure you remove the observer again
anObserver.observedButton?.removeObserver(item, forKeyPath: "highlighted")
anObserver.observedButton = nil

Update Swift 4更新 Swift 4

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

Event Button Action事件按钮操作

Show Touch On Hightlight在突出显示上显示触摸

Why not?为什么不?

@implementation UIButton (Color)

- (void) setBackgroundColor:(UIColor*)color forState:(UIControlState)state
{
    [self setBackgroundImage:[UIImage.alloc initWithCIImage:[CIImage imageWithColor:[CIColor colorWithCGColor:color.CGColor]]] forState:state];
}

@end

I can set the background color for a button but I can't work out how to set the background color for UIControlState.Highlighted .我可以为按钮设置背景颜色,但是无法确定如何为UIControlState.Highlighted设置背景颜色。 Is it even possible?可能吗? or do I need to go down the setBackgroundImage path?还是我需要沿着setBackgroundImage路径走下去?

in Swift 5在斯威夫特 5

For those who don't want to use colored background to beat the selected state对于那些不想使用彩色背景来击败选定状态的人

Simply you can beat the problem by using #Selector & if statement to change the UIButton colors for each state individually easily简单地,您可以通过使用 #Selector & if 语句轻松地单独更改每个状态的 UIButton 颜色来解决问题

For Example:例如:

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

@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

    }
}

You can override isHighlighted and changed the background color when the isHighlighted is set.当设置isHighlighted时,您可以覆盖isHighlighted并更改背景颜色。

Example: TextButton.Swift示例:TextButton.Swift

import UIKit

class TextButton: UIButton {

   private var text: String = "Submit" {
       didSet{
           setText()
       }
   }

   var hightlightedColor : UIColor = UIColor(red: 50/255, green: 50/255, blue: 50/255, alpha: 1)

   var background :UIColor = .black {
       didSet{
           self.backgroundColor = background
       }
   }

   override var isHighlighted: Bool {
       didSet {
           self.backgroundColor = self.isHighlighted ? hightlightedColor : background
       }
   }

   // MARK: - Lifecycle
   override init(frame: CGRect) {
       super.init(frame: frame)
       sharedLayout()
   }

   required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
       sharedLayout()
   }



   // MARK: - Method
   private func setText() {
       self.setTitle(text, for: .normal)
   }

   private func sharedLayout() {
       self.setTitle(text, for: .normal)
       self.backgroundColor = self.isHighlighted ? .green : background
       self.layer.cornerRadius = 8
   }

} }

Usages:用途:

let nextBtn = TextButton()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM