web-dev-qa-db-fra.com

Comment définir la couleur d'arrière-plan UIButton pour State: UIControlState.Highlighted in Swift

Je peux définir la couleur d'arrière-plan d'un bouton, mais je ne peux pas déterminer comment définir la couleur d'arrière-plan pour UIControlState.Highlighted. Est-ce même possible? ou dois-je descendre le chemin setBackgroundImage?

40
David Wood

Si quelqu'un passe par là, une autre solution serait peut-être plus facile si vous en avez besoin plus d'une fois ... J'ai écrit une courte extension pour UIButton, cela fonctionne parfaitement:

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

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

Vous l'utilisez comme setBackgroundImage:

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

La syntaxe passe à @ winterized extension pour la syntaxe de Swift 3+

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

Vous trouverez ci-dessous une solution. Deux IBActions. Un pour contrôler la couleur de fond lorsque vous appuyez sur un bouton, un pour relâcher.

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

    }
}

Lorsque vous examinez les options de saisie semi-automatique de votre bouton après l'ajout d'un point, vous pouvez définir une couleur d'arrière-plan, mais pas pour l'état spécifié. Vous pouvez uniquement définir des images d'arrière-plan. Maintenant, bien sûr, si vous êtes marié à le faire de cette façon au lieu d'utiliser la méthode que je montre ci-dessus, vous pouvez charger une image de la couleur souhaitée en tant qu'image d'arrière-plan à l'aide de la propriété setbackgroundImageForState.

enter image description here

enter image description here

16
Steve Rosenberg

Swift 4 Version de cette solution :

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

Compatibilité Swift 4+ pour la réponse acceptée:

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 et corrigez le bogue de la disposition automatique/rayon de coin cassé.

4
Maximelc

Mise à jour 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)
    }

Action du bouton d'événement

Afficher Touch On Highlight

4
Puji Wahono

Il semble que personne ici n'ait encore mentionné l'utilisation de Key Value Observation, mais c'est une autre approche.

Une raison de le faire au lieu de choisir les autres réponses ici est que vous n'avez pas besoin de créer de nouvelles images tout le temps ni de vous préoccuper des effets secondaires d'attribution d'images à des boutons (par exemple des effets cornerRadius).

Mais vous devrez créer une classe pour l'observateur, qui serait chargé de stocker les différentes couleurs d'arrière-plan et de les appliquer dans la méthode 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
    }
}

}

Il vous suffit ensuite de gérer addObserver/removeObserver pendant son fonctionnement:

// 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
3
Mete

Pourquoi pas?

@implementation UIButton (Color)

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

@end
2
poGUIst

Pouvons-nous faire la même chose en utilisant des attributs d'exécution?

@IBInspectable var HighlightedBackground: Bool {
            get {
                return true
            }
           set {
            layer.backgroundColor = Common.sharedInstance.OrangeColor.CGColor
                print("highlighted state")
            }
        }
1
Sonika Sood