繁体   English   中英

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

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

我可以设置按钮的背景颜色,但我不知道如何设置UIControlState.Highlighted的背景颜色。 甚至可能吗? 还是我需要沿着setBackgroundImage路径走下去?

如果有人停下来,如果你不止一次需要它,那么另一种方式可能更容易......我为 UIButton 编写了一个简短的扩展,它工作得很好:

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

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

您可以像使用setBackgroundImage一样使用它:

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

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

下面将是一种方法。 两个 IBAction。 按下按钮时控制背景颜色,释放时控制背景颜色。

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

    }
}

添加句点后查看按钮的自动完成选项时,您可以设置背景颜色,但不能设置指定状态。 您只能设置背景图像。 现在,当然,如果您愿意这样做而不是使用我上面展示的方法,您可以使用 setbackgroundImageForState 属性加载所需颜色的图像作为背景图像。

在此处输入图片说明

在此处输入图片说明

已接受答案的 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)
  }
}

兼容 SwiftLint 并修复自动布局/圆角半径损坏的错误。

此解决方案的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)
    }
}

似乎这里没有人提到使用Key Value Observation ,但这是另一种方法。

这样做而不是在这里选择其他答案的一个原因是您不需要一直创建新图像,也不需要关心将图像分配给按钮的次要效果(例如,cornerRadius 效果)。

但是您需要为观察者创建一个类,该类负责存储不同的背景颜色并将它们应用到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
    }
}

}

然后你需要做的就是在操作过程中管理 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

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

事件按钮操作

在突出显示上显示触摸

为什么不?

@implementation UIButton (Color)

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

@end

我可以为按钮设置背景颜色,但是无法确定如何为UIControlState.Highlighted设置背景颜色。 可能吗? 还是我需要沿着setBackgroundImage路径走下去?

在斯威夫特 5

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

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

例如:

    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

    }
}

当设置isHighlighted时,您可以覆盖isHighlighted并更改背景颜色。

示例: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
   }

}

用途:

let nextBtn = TextButton()

暂无
暂无

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

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