Como alterar a cor de fundo de um UIButton enquanto está realçado?

236

Em algum momento do meu aplicativo, tenho um destaque UIButton (por exemplo, quando um usuário coloca o dedo no botão) e preciso alterar a cor do plano de fundo enquanto o botão está realçado (enquanto o dedo do usuário ainda está no botão) .

Eu tentei o seguinte:

_button.backgroundColor = [UIColor redColor];

Mas isto não está funcionando. A cor permanece a mesma. Tentei o mesmo pedaço de código quando o botão não está destacado e funciona bem. Eu também tentei ligar-setNeedsDisplay depois de mudar a cor, não teve nenhum efeito.

Como forçar o botão para alterar a cor do plano de fundo?

MartinMoizard
fonte

Respostas:

411

Você pode substituir UIButtono setHighlightedmétodo.

Objetivo-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
    }
}
Thomas Decaux
fonte
Sim. É uma boa maneira de fazer isso. Porque você pode definir vários botões semelhantes.
Paul Brewczynski 22/03
3
Apenas uma pergunta para iniciantes, onde você subclasse esse método de botão? Se eu tiver um botão em um controlador de exibição chamado ConversionViewController, como eu configuraria o botão para alterar a cor de fundo quando destacado ou tocado? Subclassifico o setHIghlighted no COnversionViewController?
precisa saber é o seguinte
Portanto, há um problema com esta resposta que encontrei. Se você quiser que a mesma cor esteja disponível quando você selecionar o botão, setHighlighted será chamado após setSelected e, portanto, substituirá qualquer estilo selecionado que você tiver. A solução acima poderia ser melhor se você quiser selecionar o botão bem
HaloZero
3
@YakivKovalskiy assumindo que você está usando uma subclasse, você pode adicionar duas propriedades UIColor, por exemplo, normalBackground e featuredBackground, e atribuir self.backgroundColor = normalBackground ou featuredBackground de acordo. Não se esqueça de adicionar um método init para facilitar o uso, por exemplo, initWithBackground: featuredBackground:
SK.
2
Solução agradável, apenas uma sugestão:backgroundColor = isHighlighted ? .lightGray : .white
Fantini
298

Não tenho certeza se isso resolve o que você procura, ou se encaixa no seu cenário geral de desenvolvimento, mas a primeira coisa que eu tentaria seria alterar a cor de fundo do botão no evento touchDown.

Opção 1:

Você precisaria de dois eventos para capturar, o UIControlEventTouchDown seria para quando o usuário pressionar o botão. UIControlEventTouchUpInside e UIControlEventTouchUpOutside serão para quando liberarem o botão para retorná-lo ao estado 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];

Opção 2:

Retorne uma imagem criada com a cor de destaque desejada. Isso também pode ser uma 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 altere o estado destacado do botão:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];
Tim
fonte
3
Adicione UIControlEventTouchUpOutside e UIControlEventTouchCancel ao buttonHighlight: lista de eventos e ele funcionará sempre.
Evgen Bodunov 22/01
A opção dois é a melhor que encontrei até agora. Eu acho, no entanto, que os storyboards têm suas vantagens neste caso!
Jack Solomon
Resposta por Thomas é melhor e é isso que eu uso também
Van Du Tran
26
Se você estiver usando layer.cornerRadiuse optar pela opção 2, precisará definir clipsToBoundscomo true para arredondar os cantos da imagem.
Sky
3
Se alguém parar e precisar de uma resposta no Swift: stackoverflow.com/questions/26600980/…
winterized
94

Não há necessidade de substituir highlightedcomo propriedade computada. Você pode usar o observador de propriedades para acionar a alteração da cor de fundo:

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
fonte
1
Eu nunca usei uma funcionalidade como esta. Você pode explicar para onde isso vai? Está na função buttonAIBActionPress ou no viewDidLoad?
Dave G.
E se eu tiver vários UIButtons com cores diferentes?
Slavcho 11/08/16
6
@ Dave G, você cria uma nova subclasse de UIButton clicando File>New>File>Cocoa Touch Classe configurando-a como subclass of UIButton. Nomeie o arquivo para ex CustomButton, que se tornará o nome do arquivo e o nome da classe. Dentro deste arquivo, coloque o override var highlightedcódigo mostrado acima. Última etapa, defina o UIButton no Interface Builder para usar essa CustomButtonsubclasse, indo para a página Propriedade, onde diz "Classe Personalizada" e possui uma caixa suspensa. Ele diz "UIButton" em letras cinza. A lista suspensa deve mostrar CustomButton. Selecione isso e o botão agora está subclassificado.
James Toomey
Por que ninguém mencionou que o setter está sendo chamado apenas quando você toca no botão, mas não durante o layout inicial! Portanto, por padrão, não há cores até você tocar no botão.
Dmitrii
Portanto, para fazê-lo funcionar, você também precisa chamar explicitamente isHighlighted = falseem algum lugar no começo (por exemplo, na inicialização).
Dmitrii
50

Uma extensão genérica útil no 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
fonte
45

No Swift, você pode substituir o acessador da propriedade destacada (ou selecionada) em vez de substituir o método setHighlighted

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }
Jake Hall
fonte
Isso totalmente funciona, mas estou confuso como você conseguiu descobrir isso? Os parâmetros não estão na documentação ou no UIButton.h, até onde eu sei.
Shimizu
1
Essa é a sintaxe rápida que emula o comportamento de substituir setHightlighted no objetivo c. Consulte a documentação em Propriedades computadas aqui developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Jake Hall
11
Em swift você pode usar didSet
Dam
1
Adicionei exemplo com o observador de propriedades: stackoverflow.com/a/29186375/195173 .
Aleksejs Mjaliks 21/03
Eu acho que o que @shimizu estava perguntando era como você sabia que highlightedera uma propriedade no UIButton. A resposta é que é uma propriedade no UIControl da qual o UIButton herda.
Adam Johns
25

Substituir variável destacada. A adição @IBInspectablefaz com que você edite a backgroundColor destacada no storyboard, que também é bacana.

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
        }
    }
}
amassar
fonte
20

uma solução mais compacta (com base na resposta @ 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 você não deseja substituir, esta é uma versão atualizada da resposta 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
fonte
@FedericoZanetello, isso substituirá o isHighlighted em todos os botões do seu aplicativo, o que não é uma boa solução na minha opinião. vou com a resposta de Timur.
Osama bin Attique
13

Extensão UIButton com sintaxe do 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)
    }}

Use-o como:

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

Resposta original: https://stackoverflow.com/a/30604658/3659227

Maverick
fonte
10

Aqui está uma abordagem no Swift, usando uma extensão UIButton para adicionar um IBInspectable, chamado featuredBackgroundColor. Semelhante à subclasse, sem exigir uma subclasse.

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

Eu espero que isso ajude.

Fostah
fonte
1
Para SWIFT 2.0, você precisará atualizar a chamada para objc_setAssociatedObject usar um enum: objc_setAssociatedObject (self, e NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Eli Burke
Definitivamente, o melhor caminho para Swift, se você quiser manter tudo no Storyboard.
Davidethell
1
Eu prefiro usar subclasse não extensão como isso vai afetar todo o aplicativo
Hossam Ghareeb
9

Minha melhor solução para o Swift 3+ sem subclassificação.

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

Com essa extensão, é fácil gerenciar cores para diferentes estados e desbotará sua cor normal automaticamente, caso a cor destacada não seja fornecida.

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

ATUALIZAR:

Use a biblioteca UIButtonBackgroundColor Swift.

VELHO:

Use os ajudantes abaixo para criar uma imagem de 1 px x 1 px com uma cor de preenchimento em escala de cinza:

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

ou uma cor de preenchimento RGB:

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

Em seguida, use isso imagepara definir a imagem de fundo do botão:

[button setBackgroundImage:image forState:UIControlStateNormal];

Ajudantes

#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é o prefixo da classe da minha biblioteca estática do Cocoa Touch chamada Acani Utilities, em que AC é para Acani e U é para Utilities.

ma11hew28
fonte
4

Tente isso !!!!

Para Evento TouchedDown, defina Uma cor e, para TouchUpInside, defina a outra.

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

- (IBAction)touchUpInside:(id)sender {
    NSLog(@"TouchUpInside");
    btn1.backgroundColor=[UIColor whiteColor];    
}
Karan Alangat
fonte
2
Trabalhou para mim. Eu apenas precisei adicionar - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {para garantir que a cor não permaneça acesa quando o usuário acidentalmente puxa o dedo do botão.
SudoPlz 03/02
4

Subclasse o UIButton e adicione propriedades inspecionáveis ​​para uso conveniente (escrito no 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
fonte
3

Você pode subclassificar o UIButton e criar um bom 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

Notas (Este é um exemplo, eu sei que há problemas e aqui estão alguns)

Eu usei um NSMutableDictionay para armazenar o UIColor para cada estado, tenho que fazer uma conversão de texto desagradável para a chave, pois o UIControlState não é um bom int direto. Se você pudesse iniciar uma matriz com tantos objetos e usar o estado como um índice.

Por causa disso, muitos têm dificuldades com, por exemplo, um botão selecionado e desativado, é necessária alguma lógica.

Outro problema é que, se você tentar definir várias cores ao mesmo tempo, eu não tentei com um botão, mas se você puder fazer isso, pode não funcionar

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

Eu assumi que este é o StoryBoard, não há init, initWithFrame, então adicione-os se precisar.

Aço reciclado
fonte
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 , obrigado @Maverick

dengST30
fonte
3

Detalhes

  • Xcode 11.1 (11A1027), Swift 5

Solução

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)
Vasily Bodnarchuk
fonte
2

Tente isso se você tiver uma imagem:

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

ou veja se showsTouchWhenHighlightedé o suficiente para você.

Siby
fonte
Tentei brincar com showsTouchWhenHighlighted, mas não ajudou. Não quero usar setBackgroundImage: forState :. Na verdade, eu estava tentando usar o backgroundColor para não usar nenhuma imagem.
precisa saber é o seguinte
2

Eu tenho código aberto uma subclasse UIButton , STAButton , para preencher esse buraco de funcionalidade. Disponível sob a licença MIT. Funciona para iOS 7 ou superior (não testei com versões mais antigas do iOS).

Stunner
fonte
2

Para resolver esse problema, criei uma categoria para lidar backgroundColorcom os estados com UIButtons:
ButtonBackgroundColor-iOS

Você pode instalar a categoria como um pod .

Fácil de usar com Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

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

Ainda mais fácil de usar com o Swift :

import ButtonBackgroundColor

...

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

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

Eu recomendo que você importe o pod com:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Usando use_frameworks! no seu Podfile facilita o uso de seus pods com Swift e objetivo-C.

IMPORTANTE

Também escrevi uma postagem no blog com mais informações.

Gabriel.Massana
fonte
2
class CustomButton: UIButton {

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

}
evya
fonte
2

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

Adicionar ao Podfile usando CocoaPods

pod "UIButtonSetBackgroundColorForState"

Rápido

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

Objetivo-C

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
raio de espada
fonte
1

Tente tintColor:

_button.tintColor = [UIColor redColor];
jjv360
fonte
Tem certeza de que está vinculado no IB? O que você ganha se você faz NSLog(@"%@", _button);?
Jjv360
1
Isso não funcionará se você estiver usando um UIButtonTypeCustom.
JaredH
1

Aqui está o código no Swift para selecionar o estado do botão:

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

Exemplo:

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

Solte-o e
pronto : * a propriedade pode ser definida no IB e, se nenhum fundo realçado estiver definido, o fundo não será alterado quando pressionado

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
        }
    }
}
sapato
fonte
1

A UIIImageextensão abaixo gera um objeto de imagem com o parâmetro de cor especificado.

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

Um exemplo de uso de um botão pode ser aplicado ao objeto de botão como:

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
fonte
1

simples é usar esse UIButton Extension ONLY

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 use isso

 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
fonte
0

se você não substituir, defina duas ações touchDown touchUpInside

Roman Bambura
fonte
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
fonte
0

no Swift 5

Para quem não quer usar plano de fundo colorido para vencer o estado selecionado

Simplesmente, você pode superar o problema usando a instrução #Selector & if para alterar as cores UIButton de cada estado individualmente facilmente

Por exemplo:

    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
fonte