Come cambiare il colore di sfondo di un UIButton mentre è evidenziato?


236

Ad un certo punto nella mia app ho evidenziato UIButton(ad esempio quando un utente ha il dito sul pulsante) e ho bisogno di cambiare il colore di sfondo mentre il pulsante è evidenziato (quindi mentre il dito dell'utente è ancora sul pulsante) .

Ho provato quanto segue:

_button.backgroundColor = [UIColor redColor];

Ma non sta funzionando. Il colore rimane lo stesso. Ho provato lo stesso codice quando il pulsante non è evidenziato e funziona perfettamente. Ho anche provato a chiamare -setNeedsDisplaydopo aver cambiato il colore, non ha avuto alcun effetto.

Come forzare il pulsante per cambiare il colore di sfondo?


Risposte:


411

Puoi ignorare UIButtonil setHighlightedmetodo.

Objective-C

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

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

Swift 3.0 e Swift 4.1

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

Si. È un bel modo per farlo. Perché puoi definire diversi pulsanti simili.
Paul Brewczynski,

3
Solo una domanda da principiante, dove dovresti sottoclassare quel metodo pulsante? Se ho un pulsante in un controller di visualizzazione denominato ConversionViewController, come imposterò il pulsante per cambiare il colore di sfondo quando evidenziato o toccato? Dovrei sottoclassare il setHIghlighted in COnversionViewController?
Batrimonio1116

Quindi c'è un problema con questa risposta che ho trovato. Se si desidera avere lo stesso colore disponibile quando si seleziona il pulsante, setHighlighted viene chiamato dopo setSelected e quindi sovrascriverà qualsiasi stile selezionato che si possiede. La soluzione sopra potrebbe essere migliore se si desidera selezionare anche il pulsante
HaloZero,

3
@YakivKovalskiy supponendo che tu stia utilizzando una sottoclasse, potresti aggiungere due proprietà UIColor, ad esempio normalBackground ed highlightBackground, quindi assegnare di conseguenza self.backgroundColor = normalBackground o highlightBackground. Non dimenticare di aggiungere un metodo init per facilità d'uso, ad esempio initWithBackground: highlightBackground:
SK.

2
Bella soluzione, solo un suggerimento:backgroundColor = isHighlighted ? .lightGray : .white
Fantini

298

Non sono sicuro che questo tipo di risolva ciò che stai cercando, o si adatti al tuo panorama di sviluppo generale, ma la prima cosa che proverei sarebbe quella di cambiare il colore di sfondo del pulsante sull'evento touchDown.

Opzione 1:

Avresti bisogno di due eventi per essere catturato, UIControlEventTouchDown sarebbe per quando l'utente preme il pulsante. UIControlEventTouchUpInside e UIControlEventTouchUpOutside serviranno quando rilasciano il pulsante per riportarlo allo stato normale

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

Opzione 2:

Restituisce un'immagine creata con il colore di evidenziazione desiderato. Questa potrebbe anche essere una categoria.

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

e quindi modificare lo stato evidenziato del pulsante:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];

3
Aggiungi UIControlEventTouchUpOutside e UIControlEventTouchCancel a buttonHighlight: elenco eventi e funzionerà sempre.
Evgen Bodunov,

L'opzione due è la migliore che ho trovato finora. Immagino, tuttavia, che gli storyboard abbiano i loro vantaggi in questo caso!
Jack Solomon,

La risposta di Thomas è migliore ed è quello che uso anche io
Van Du Tran

26
Se stai usando layer.cornerRadiuse vai con l'opzione # 2, dovrai assicurarti di impostare clipsToBoundssu true per arrotondare anche gli angoli dell'immagine.
Sky

3
Se qualcuno si ferma e ha bisogno di una risposta in Swift: stackoverflow.com/questions/26600980/…
Winterized

94

Non è necessario eseguire highlightedl' override come proprietà calcolata. È possibile utilizzare l'osservatore di proprietà per attivare la modifica del colore di sfondo:

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

1
Non ho mai usato funzionalità come questa. Puoi spiegare dove va? Si trova nella funzione IBAction buttonPress o in viewDidLoad?
Dave G,

Cosa succede se ho più UIButton con colori diversi?
Slavcho,

6
@Dave G, si crea una nuova sottoclasse di UIButton facendo clic File>New>File>Cocoa Touch Classe impostandolo su subclass of UIButton. Denominare il file per ex CustomButton, che diventerà sia il nome del file che il nome della classe. All'interno di questo file, inserisci il override var highlightedcodice mostrato sopra. Ultimo passaggio, imposta UIButton su Interface Builder per utilizzare questa CustomButtonsottoclasse andando alla pagina Proprietà dove dice "Classe personalizzata" e ha una casella a discesa. Dirà "UIButton" in lettere grigie. L'elenco a discesa dovrebbe mostrare CustomButton. Selezionare questo e il pulsante è ora sottoclassato.
James Toomey,

Perché nessuno aveva menzionato che il setter viene chiamato solo quando si tocca il pulsante, ma non durante il layout iniziale! Quindi, per impostazione predefinita, non c'è colore finché non si tocca il pulsante.
Dmitrii,

Quindi, per farlo funzionare, devi anche chiamare esplicitamente isHighlighted = falseda qualche parte all'inizio (ad esempio sull'inizializzazione).
Dmitrii,

50

Una comoda estensione generica in 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)
    }
}

45

In Swift puoi sovrascrivere l'accessor della proprietà evidenziata (o selezionata) anziché sovrascrivere il metodo setHighlighted

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

Funziona totalmente, ma sono confuso su come sei riuscito a capirlo? I parametri non sono nella documentazione o UIButton.h per quanto ne so.
shimizu,

1
Questa è la sintassi rapida che emula il comportamento del set prevalente Evidenziato nell'obiettivo c. Consulta la documentazione sulle proprietà calcolate qui developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Jake Hall

11
In breve tempo puoi usare didSet
Dam

1
Ho aggiunto un esempio con l'osservatore di proprietà: stackoverflow.com/a/29186375/195173 .
Aleksejs Mjaliks,

Penso che ciò che @shimizu stava chiedendo fosse come sapevi che highlightedera una proprietà su UIButton. La risposta è che è una proprietà su UIControl da cui UIButton eredita.
Adam Johns,

25

Sostituisci variabile evidenziata. L'aggiunta @IBInspectableti consente di modificare lo sfondo evidenziato in Storyboard, che è anche carino.

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

20

una soluzione più compatta (basata sulla risposta di @ 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()
    }
}

Se non desideri eseguire l'override, questa è una versione aggiornata della risposta di @ 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 questo sovrascriverà isHighlighted in tutti i pulsanti della tua app, che secondo me non è una buona soluzione. andrò con la risposta di Timur.
Usama bin Attique,

13

Estensione UIButton con sintassi 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)
    }}

Usalo come:

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

Risposta originale: https://stackoverflow.com/a/30604658/3659227


10

Ecco un approccio in Swift, usando un'estensione UIButton per aggiungere un IBInspectable, chiamato highlightBackgroundColor. Simile alla sottoclasse, senza richiedere una sottoclasse.

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

Spero che aiuti.


1
Per swift 2.0, dovrai aggiornare la chiamata a objc_setAssociatedObject per usare un enum: objc_setAssociatedObject (self, e NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Eli Burke

Sicuramente il modo migliore in Swift se vuoi tenere tutto nello Storyboard.
davidethell,

1
Preferisco usare la sottoclasse non l'estensione poiché ciò influirà sull'intera app
Hossam Ghareeb,


9

La mia migliore soluzione per Swift 3+ senza sottoclasse.

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

Con questa estensione è facile gestire i colori per diversi stati e sbiadirà automaticamente il tuo colore normale nel caso in cui non venga fornito il colore evidenziato.

button.setBackgroundColor(.red, for: .normal)

4

AGGIORNARE:

Utilizzare la libreria UIButtonBackgroundColor Swift.

VECCHIO:

Utilizza gli helper di seguito per creare un'immagine di 1 px x 1 px con un colore di riempimento in scala di grigi:

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

o un colore di riempimento RGB:

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

Quindi, usalo imageper impostare l'immagine di sfondo del pulsante:

[button setBackgroundImage:image forState:UIControlStateNormal];

Helpers

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

Nota: ACUè il prefisso di classe della mia libreria statica Cocoa Touch chiamata Acani Utilities, dove AC è per Acani e U è per Utilità.


4

Prova questo !!!!

Per TouchedDown Event impostare un colore e per TouchUpInside impostare l'altro.

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

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

2
Ha funzionato per me. Ho dovuto solo aggiungere - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {per assicurarsi che il colore non rimanesse acceso quando l'utente trascina accidentalmente il dito dal pulsante.
SudoPlz,

4

Sottoclasse UIButton e aggiungi proprietà ispezionabili per un uso conveniente (scritto in 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
            }
        }
    }
}

3

È possibile sottoclassare il pulsante UIB e creare un ottimo stato.

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

Appunti (Questo è un esempio, so che ci sono problemi e qui ce ne sono alcuni)

Ho usato un NSMutableDictionay per memorizzare l'UIColor per ogni stato, devo fare una brutta conversione di testo per la chiave poiché UIControlState non è un bel int. Se fosse possibile avviare una matrice con tanti oggetti e utilizzare lo stato come indice.

Per questo motivo molti hanno difficoltà ad es. Con un pulsante selezionato e disabilitato, è necessaria un po 'più di logica.

Un altro problema è che se provi a impostare più colori contemporaneamente, non ho provato con un pulsante, ma se riesci a farlo potrebbe non funzionare

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

Ho supposto che questo sia StoryBoard, non c'è init, initWithFrame quindi aggiungili se ne hai bisogno.


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 , grazie @Maverick


3

Dettagli

  • Xcode 11.1 (11A1027), Swift 5

Soluzione

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

uso

button.setBackground(.green, for: .normal)

2

Prova questo se hai un'immagine:

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

o vedi se showsTouchWhenHighlightedè abbastanza per te.


Ho provato a giocare con gli spettacoli TouchWhenHighlighted ma non è stato d'aiuto. Non voglio usare setBackgroundImage: forState :. In effetti stavo provando a usare backgroundColor per non usare alcuna immagine.
MartinMoizard,

2

Ho creato una sottoclasse UIButton , STAButton , per riempire questo buco di funzionalità gaping. Disponibile sotto licenza MIT. Funziona con iOS 7+ (non ho testato con versioni iOS precedenti).


2

Per risolvere questo problema ho creato una Categoria per gestire gli backgroundColorStati con UIButtons:
ButtonBackgroundColor-iOS

È possibile installare la categoria come pod .

Facile da usare con Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

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

Ancora più facile da usare con Swift :

import ButtonBackgroundColor

...

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

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

Ti consiglio di importare il pod con:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Usando use_frameworks! nel tuo Podfile è più facile usare i tuoi pod con Swift e goal-C.

IMPORTANTE

Ho anche scritto un post sul blog con maggiori informazioni.


2
class CustomButton: UIButton {

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

}


1

Prova tintColor:

_button.tintColor = [UIColor redColor];

Sei sicuro che sia collegato in IB? Cosa ottieni se lo fai NSLog(@"%@", _button);?
jjv360,

1
Questo non funzionerà se stai usando a UIButtonTypeCustom.
JaredH,

1

Ecco il codice in Swift per selezionare lo stato del pulsante:

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

Esempio:

    self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)

1


Inseriscilo e sei a posto: * la proprietà può essere impostata in IB, e se non è impostato uno sfondo evidenziato, lo sfondo non cambierà quando viene premuto

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

1

L' UIIImageestensione sottostante genera l'oggetto immagine con il parametro colore specificato.

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 utilizzo di esempio per un pulsante può essere applicato per l'oggetto pulsante come:

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)

1

è semplice utilizzare SOLO l'estensione 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)
        }
    }

}

e usa questo

 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)


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

0

in Swift 5

Per coloro che non vogliono usare lo sfondo colorato per battere lo stato selezionato

Semplicemente puoi risolvere il problema usando #Selector e l'istruzione if per cambiare facilmente i colori dei pulsanti UIB per ogni stato individualmente

Per esempio:

    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

    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.