Comment changer la couleur d'arrière-plan d'un bouton UIB lorsqu'il est en surbrillance?

236

À un certain moment dans mon application, j'ai mis en surbrillance UIButton(par exemple, lorsqu'un utilisateur a le doigt sur le bouton) et je dois changer la couleur d'arrière-plan pendant que le bouton est en surbrillance (donc pendant que le doigt de l'utilisateur est toujours sur le bouton) .

J'ai essayé ce qui suit:

_button.backgroundColor = [UIColor redColor];

Mais ça ne fonctionne pas. La couleur reste la même. J'ai essayé le même morceau de code lorsque le bouton n'est pas mis en surbrillance et cela fonctionne bien. J'ai également essayé d'appeler -setNeedsDisplayaprès avoir changé la couleur, cela n'a eu aucun effet.

Comment forcer le bouton à changer la couleur de fond?

MartinMoizard
la source
Consultez ce post quelque choseaboutios.wordpress.com/2016/02/09/…
Gabriel.Massana

Réponses:

411

Vous pouvez remplacer UIButtonla setHighlightedméthode de.

Objectif c

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];

    if (highlighted) {
        self.backgroundColor = UIColorFromRGB(0x387038);
    } else {
        self.backgroundColor = UIColorFromRGB(0x5bb75b);
    }
}

Swift 3.0 et Swift 4.1

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.black : UIColor.white
    }
}
Thomas Decaux
la source
Ouais. C'est plutôt sympa de le faire. Parce que vous pouvez définir plusieurs boutons similaires.
Paul Brewczynski
3
Juste une question de débutant, où sous-classeriez-vous cette méthode de bouton? Si j'ai un bouton dans un contrôleur de vue nommé ConversionViewController, comment configurer le bouton pour changer la couleur d'arrière-plan lorsqu'il est mis en surbrillance ou appuyé? Dois-je sous-classer le setHIghlighted dans le COnversionViewController?
Beanno1116
Il y a donc un problème avec cette réponse que j'ai trouvé. Si vous souhaitez que la même couleur soit disponible lorsque vous sélectionnez le bouton, alors setHighlighted est appelé après setSelected et remplacera ainsi tout style sélectionné. La solution ci-dessus pourrait être meilleure si vous souhaitez également sélectionner le bouton
HaloZero
3
@YakivKovalskiy en supposant que vous utilisez une sous-classe, vous pouvez ajouter deux propriétés UIColor, par exemple normalBackground et highlightBackground, puis attribuer self.backgroundColor = normalBackground ou highlightBackground en conséquence. N'oubliez pas d'ajouter une méthode init pour la facilité d'utilisation, par exemple initWithBackground: highlightBackground:
SK.
2
Belle solution, une seule suggestion:backgroundColor = isHighlighted ? .lightGray : .white
Fantini
298

Je ne sais pas si ce type de solution résout ce que vous recherchez ou correspond à votre paysage de développement général, mais la première chose que j'essaierais serait de changer la couleur d'arrière-plan du bouton de l'événement touchDown.

Option 1:

Vous auriez besoin de deux événements pour être capturé, UIControlEventTouchDown le serait lorsque l'utilisateur appuie sur le bouton. UIControlEventTouchUpInside et UIControlEventTouchUpOutside seront pour quand ils relâcheront le bouton pour le ramener à l'état normal

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:

Renvoyez une image réalisée à partir de la couleur de surbrillance souhaitée. Cela pourrait également être une catégorie.

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

puis modifiez l'état en surbrillance du bouton:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];
Tim
la source
3
Ajoutez UIControlEventTouchUpOutside et UIControlEventTouchCancel à buttonHighlight: liste d'événements et cela fonctionnera toujours.
Evgen Bodunov
La deuxième option est la meilleure que j'ai trouvée jusqu'à présent. Je suppose, cependant, que les storyboards ont leurs avantages dans ce cas!
Jack Solomon
La réponse de Thomas est meilleure et c'est ce que j'utilise aussi
Van Du Tran
26
Si vous utilisez layer.cornerRadiuset optez pour l'option # 2, vous devrez vous assurer de régler clipsToBoundssur true pour arrondir également les coins de l'image.
Sky
3
Si quelqu'un s'arrête et a besoin d'une réponse dans Swift: stackoverflow.com/questions/26600980/…
winterized
94

Il n'est pas nécessaire de remplacer highlightedla propriété calculée. Vous pouvez utiliser l'observateur de propriétés pour déclencher un changement de couleur d'arrière-plan:

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
    }
}
Aleksejs Mjaliks
la source
1
Je n'ai jamais utilisé de fonctionnalités comme celle-ci. Pouvez-vous expliquer où cela va? Est-ce dans la fonction IBAction buttonPress ou dans viewDidLoad?
Dave G
Que faire si j'ai plusieurs boutons UIB de différentes couleurs?
Slavcho
6
@Dave G, vous créez une nouvelle sous-classe d'UIButton en cliquant File>New>File>Cocoa Touch Classdessus et en la définissant sur subclass of UIButton. Nommez le fichier par ex CustomButton, qui deviendra à la fois le nom de fichier et le nom de classe. Dans ce fichier, mettez le override var highlightedcode ci-dessus. Dernière étape, définissez le UIButton sur Interface Builder pour utiliser cette CustomButtonsous - classe en accédant à la page des propriétés où il est indiqué "Classe personnalisée" et comporte une zone de liste déroulante. Il indiquera "UIButton" en lettres grises. La liste déroulante doit afficher CustomButton. Sélectionnez-le et le bouton est maintenant sous-classé.
James Toomey
Pourquoi personne n'avait mentionné que le setter est appelé uniquement lorsque vous appuyez sur le bouton, mais pas pendant la mise en page initiale! Donc, par défaut, il n'y a pas de couleur tant que vous ne touchez pas le bouton.
Dmitrii
Donc, pour que cela fonctionne, vous devez également appeler explicitement isHighlighted = falsequelque part au début (lors de l'initialisation par exemple).
Dmitrii
50

Une extension générique pratique dans 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)
    }
}
Giordano Scalzo
la source
45

Dans Swift, vous pouvez remplacer l'accesseur de la propriété mise en surbrillance (ou sélectionnée) plutôt que de remplacer la méthode setHighlighted

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }
Jake Hall
la source
Cela fonctionne totalement, mais je ne sais pas comment vous avez pu comprendre cela? Les paramètres ne sont pas dans la documentation ou UIButton.h pour autant que je sache.
shimizu
1
Il s'agit de la syntaxe rapide qui émule le comportement de setHightlighted prioritaire dans l'objectif c. Voir la documentation sur les propriétés calculées ici developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Jake Hall
11
En rapide, vous pouvez utiliser didSet
Dam
1
J'ai ajouté un exemple avec l'observateur de propriétés: stackoverflow.com/a/29186375/195173 .
Aleksejs Mjaliks
Je pense que ce que @shimizu demandait, c'était comment saviez-vous que highlightedc'était une propriété sur UIButton. La réponse est que c'est une propriété sur UIControl dont UIButton hérite.
Adam Johns
25

Remplacer la variable en surbrillance. L'ajout @IBInspectablevous permet de modifier la couleur de fond mise en surbrillance dans le storyboard, ce qui est également très pratique.

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
        }
    }
}
purée
la source
20

une solution plus compacte (basée sur la réponse @ aleksejs-mjaliks ):

Swift 3/4 + :

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

Swift 2:

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

Si vous ne voulez pas passer outre, il s'agit d'une version mise à jour de la réponse de @ 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)
  }
}
Federico Zanetello
la source
@FedericoZanetello, cela remplacera isHighlighted dans tous les boutons de votre application, ce qui n'est pas une bonne solution à mon avis. va mal avec la réponse de Timur.
Usama bin Attique
13

Extension UIButton avec la syntaxe 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)
    }}

Utilisez-le comme:

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

Réponse originale: https://stackoverflow.com/a/30604658/3659227

Maverick
la source
10

Voici une approche dans Swift, en utilisant une extension UIButton pour ajouter un IBInspectable, appelé highlightBackgroundColor. Similaire à la sous-classe, sans nécessiter de sous-classe.

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

J'espère que ça aide.

Fostah
la source
1
Pour swift 2.0, vous devrez mettre à jour l'appel à objc_setAssociatedObject pour utiliser une énumération: objc_setAssociatedObject (self, & NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Eli Burke
Certainement le meilleur moyen dans Swift si vous voulez tout garder dans Storyboard.
davidethell
1
Je préfère utiliser la sous-classe et non l'extension car cela affectera l'ensemble de l'application
Hossam Ghareeb
9

Ma meilleure solution pour Swift 3+ sans sous-classement.

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

Avec cette extension, il est facile de gérer les couleurs pour différents états et il décolore automatiquement votre couleur normale au cas où la couleur en surbrillance n'est pas fournie.

button.setBackgroundColor(.red, for: .normal)
Timur Bernikovich
la source
4

METTRE À JOUR:

Utilisez la bibliothèque Swift UIButtonBackgroundColor .

VIEUX:

Utilisez les aides ci-dessous pour créer une image 1 px x 1 px avec une couleur de remplissage en niveaux de gris:

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

ou une couleur de remplissage RVB:

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

Ensuite, utilisez-le imagepour définir l'image d'arrière-plan du bouton:

[button setBackgroundImage:image forState:UIControlStateNormal];

Aides

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

Remarque: ACUest le préfixe de classe de ma bibliothèque statique Cocoa Touch appelée Acani Utilities, où AC est pour Acani et U pour Utilities.

ma11hew28
la source
4

Essaye ça !!!!

Pour TouchedDown Event, définissez une couleur et pour TouchUpInside, définissez l'autre.

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

- (IBAction)touchUpInside:(id)sender {
    NSLog(@"TouchUpInside");
    btn1.backgroundColor=[UIColor whiteColor];    
}
Karan Alangat
la source
2
A travaillé pour moi. Je devais juste ajouter - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {pour m'assurer que la couleur ne reste pas activée lorsque l'utilisateur fait accidentellement glisser son doigt sur le bouton.
SudoPlz
4

Sous-classe le UIButton et ajoutez des propriétés inspectables pour une utilisation pratique (écrit dans 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
            }
        }
    }
}
Bence Pattogato
la source
3

Vous pouvez sous-classer le UIButton et faire un joli 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

Remarques (Ceci est un exemple, je sais qu'il y a des problèmes et en voici quelques-uns)

J'ai utilisé un NSMutableDictionay pour stocker l'UIColor pour chaque État, je dois faire une conversion de texte désagréable pour la clé car l'UIControlState n'est pas un joli Int droit. Si c'est là que vous pouvez initier un tableau avec autant d'objets et utiliser l'état comme index.

Pour cette raison, vous avez souvent des difficultés avec par exemple un bouton sélectionné et désactivé, un peu plus de logique est nécessaire.

Un autre problème est que si vous essayez de définir plusieurs couleurs en même temps, je n'ai pas essayé avec un bouton, mais si vous pouvez le faire, cela peut ne pas fonctionner

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

J'ai supposé que c'était StoryBoard, il n'y a pas d'init, initWithFrame alors ajoutez-les si vous en avez besoin.

Acier recyclé
la source
3
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 , merci @Maverick

dengST30
la source
3

Détails

  • Xcode 11.1 (11A1027), Swift 5

Solution

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

Usage

button.setBackground(.green, for: .normal)
Vasily Bodnarchuk
la source
2

Essayez ceci si vous avez une image:

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

ou voyez si cela showsTouchWhenHighlightedvous suffit.

Siby
la source
J'ai essayé de jouer avec showsTouchWhenHighlighted mais cela n'a pas aidé. Je ne veux pas utiliser setBackgroundImage: forState :. J'essayais en fait d'utiliser le backgroundColor pour ne pas utiliser d'image.
MartinMoizard
2

J'ai ouvert une sous-classe UIButton, STAButton , pour combler ce trou de fonctionnalité béant. Disponible sous licence MIT. Fonctionne pour iOS 7+ (je n'ai pas testé avec les anciennes versions d'iOS).

Stunner
la source
2

Pour résoudre ce problème, j'ai créé une catégorie pour gérer les backgroundColorétats avec UIButtons:
ButtonBackgroundColor-iOS

Vous pouvez installer la catégorie en tant que module .

Facile à utiliser avec Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

[self.myButton bbc_backgroundColorNormal:[UIColor redColor]
                 backgroundColorSelected:[UIColor blueColor]];

Encore plus facile à utiliser avec Swift :

import ButtonBackgroundColor

...

let myButton:UIButton = UIButton(type:.Custom)

myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())

Je vous recommande d'importer le pod avec:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Utilisation de use_frameworks! dans votre Podfile facilite l'utilisation de vos pods avec Swift et objective-C.

IMPORTANT

J'ai également écrit un article de blog avec plus d'informations.

Gabriel.Massana
la source
2
class CustomButton: UIButton {

    override var isHighlighted: Bool {
        didSet {
            if (isHighlighted) {
                alpha = 0.5
            }
            else {
                alpha = 1
            }            
        }
    }

}
evya
la source
2

Utilisez https://github.com/swordray/UIButtonSetBackgroundColorForState

Ajouter au Podfile à l'aide de CocoaPods

pod "UIButtonSetBackgroundColorForState"

Rapide

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

Objectif c

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
épée
la source
1

Essayez tintColor:

_button.tintColor = [UIColor redColor];
jjv360
la source
Êtes-vous sûr qu'il est lié dans IB? Qu'obtenez-vous si vous le faites NSLog(@"%@", _button);?
jjv360
1
Cela ne fonctionnera pas si vous utilisez un UIButtonTypeCustom.
JaredH
1

Voici le code dans Swift pour sélectionner l'état du bouton:

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

Exemple:

    self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)
Mike Zriel
la source
1

Déposez-le et vous êtes
prêt à partir: * la propriété peut être définie dans IB, et si aucun arrière-plan en surbrillance n'est défini, l'arrière-plan ne changera pas lorsque vous appuyez dessus

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
        }
    }
}
chaussure
la source
1

L' UIIImageextension ci-dessous génère un objet image avec le paramètre de couleur spécifié.

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

Un exemple d'utilisation d'un bouton peut être appliqué pour l'objet bouton comme:

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)
Manoj Kumar
la source
1

est simple, utilisez cette extension UIButton UNIQUEMENT

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

}

et utilisez ceci

 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)
Muhammad Ahmad
la source
0

si vous ne remplacez pas, définissez simplement deux actions touchDown touchUpInside

Bambura romain
la source
0

Swift 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)
    }
}
Elita
la source
0

dans Swift 5

Pour ceux qui ne veulent pas utiliser l'arrière-plan coloré pour battre l'état sélectionné

Simplement, vous pouvez vaincre le problème en utilisant l'instruction #Selector & if pour changer facilement les couleurs UIButton pour chaque état individuellement

Par exemple:

    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

    }
}
Let.Simoo
la source