Jak zmienić kolor tła przycisku UIB, gdy jest podświetlony?


236

W pewnym momencie mojej aplikacji mam wyróżnione UIButton(na przykład, gdy użytkownik trzyma palec na przycisku) i muszę zmienić kolor tła, gdy przycisk jest podświetlony (więc gdy palec użytkownika jest nadal na przycisku) .

Próbowałem następujące:

_button.backgroundColor = [UIColor redColor];

Ale to nie działa. Kolor pozostaje taki sam. Próbowałem tego samego kodu, gdy przycisk nie jest podświetlony i działa dobrze. Próbowałem też zadzwonić -setNeedsDisplaypo zmianie koloru, to nie miało żadnego efektu.

Jak zmusić przycisk do zmiany koloru tła?


Odpowiedzi:


411

Można zastąpić UIButton„s setHighlightedmetody.

Cel C

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

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

Swift 3.0 i Swift 4.1

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

Tak. To miły sposób na zrobienie tego. Ponieważ możesz zdefiniować kilka podobnych przycisków.
Paul Brewczynski

3
Tylko pytanie dla początkujących, gdzie podklasowałbyś tę metodę przycisku? Jeśli mam przycisk w kontrolerze widoku o nazwie ConversionViewController, jak mam ustawić przycisk, aby zmienić kolor tła po podświetleniu lub dotknięciu? Czy podklasowałbym setHIghlighted w COnversionViewController?
Beanno1116

Znalazłem więc jeden problem z tą odpowiedzią. Jeśli chcesz, aby ten sam kolor był dostępny po wybraniu przycisku, wówczas setHighlighted zostanie wywołany po ustawieniu SetSelected, a tym samym zastąpi wybrany styl. Powyższe rozwiązanie może być lepsze, jeśli chcesz również wybrać przycisk
HaloZero,

3
@YakivKovalskiy zakładając, że używasz podklasy, możesz dodać dwie właściwości UIColor, np. NormalBackground i podświetlony Background, a następnie odpowiednio przypisać self.backgroundColor = normalBackground lub podświetlony Background. Nie zapomnij dodać metody init dla łatwości użycia, np. InitWithBackground: podświetloneBackground:
SK.

2
Ładne rozwiązanie, tylko jedna sugestia:backgroundColor = isHighlighted ? .lightGray : .white
Fantini

298

Nie jestem pewien, czy ten rodzaj rozwiązuje to, czego szukasz, czy pasuje do ogólnego krajobrazu programistycznego, ale pierwszą rzeczą, którą spróbowałbym, byłaby zmiana koloru tła przycisku na zdarzeniu touchDown.

Opcja 1:

Potrzebne byłyby dwa zdarzenia do przechwycenia, UIControlEventTouchDown byłby potrzebny, gdy użytkownik naciśnie przycisk. UIControlEventTouchUpInside i UIControlEventTouchUpOutside będą dostępne po zwolnieniu przycisku, aby przywrócić go do normalnego stanu

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

Opcja 2:

Zwróć obraz wykonany z żądanego koloru podświetlenia. To może być także kategoria.

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

a następnie zmień podświetlony stan przycisku:

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

3
Dodaj UIControlEventTouchUpOutside i UIControlEventTouchCancel do buttonHighlight: lista zdarzeń i zawsze będzie działać.
Evgen Bodunov

Opcja druga jest najlepsza, jaką do tej pory znalazłem. Myślę jednak, że w tym przypadku storyboardy mają swoje zalety!
Jack Solomon

Odpowiedź Thomasa jest lepsza i tego też używam
Van Du Tran

26
Jeśli używasz layer.cornerRadiusi idziesz z opcją # 2, musisz upewnić się, że jest ustawiona wartość clipsToBoundstrue, aby zaokrąglić również rogi obrazu.
Sky

3
Jeśli ktoś zatrzyma się i potrzebuje odpowiedzi w Swift: stackoverflow.com/questions/26600980/…
zimuje

94

Nie ma potrzeby zastępowania highlightedjako obliczonej właściwości. Za pomocą obserwatora właściwości można wywołać zmianę koloru tła:

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

Szybki 4

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

1
Nigdy nie korzystałem z takiej funkcjonalności. Czy możesz wyjaśnić, dokąd to idzie? Czy jest to w funkcji IBAction buttonPress czy w viewDidLoad?
Dave G

Co się stanie, jeśli mam wiele przycisków UIB w różnych kolorach?
Slavcho,

6
@Dave G, tworzysz nową podklasę UIButton, klikając File>New>File>Cocoa Touch Classi ustawiając ją na subclass of UIButton. Nazwij plik np. CustomButton, Który stanie się zarówno nazwą pliku, jak i nazwą klasy. Wewnątrz tego pliku umieść override var highlightedkod pokazany powyżej. W ostatnim kroku ustaw UIButton w interfejsie Konstruktora, aby używał tej CustomButtonpodklasy, przechodząc do strony Właściwość, na której jest napisane „Klasa niestandardowa” i ma rozwijane pole. Powie „UIButton” szarymi literami. Lista rozwijana powinna zawierać CustomButton. Wybierz to, a przycisk jest teraz podklasą.
James Toomey

Dlaczego nikt nie wspomniał, że seter jest wywoływany tylko po naciśnięciu przycisku, ale nie podczas początkowego układu! Więc domyślnie nie ma koloru, dopóki nie dotkniesz przycisku.
Dmitrii

Aby więc działało, musisz również wyraźnie zadzwonić isHighlighted = falsegdzieś na początku (na przykład podczas inicjalizacji).
Dmitrii

49

Przydatne ogólne rozszerzenie w 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

W Swift możesz zastąpić akcesorium podświetlonej (lub wybranej) właściwości zamiast przesłonić metodę setHighlighted

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

To całkowicie działa, ale jestem zdezorientowany, jak udało ci się to rozgryźć? O ile mi wiadomo, parametrów nie ma w dokumentacji ani w UIButton.h.
shimizu

1
Jest to szybka składnia, która emuluje zachowanie nadpisującego setHightlighted w celu c. Zobacz dokumentację o właściwościach obliczeniowych tutaj developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Jake Hall

11
W szybki sposób można użyć didSet
Dam

1
Dodałem przykład z obserwatorem właściwości: stackoverflow.com/a/29186375/195173 .
Aleksejs Mjaliks

Myślę, że @shimizu pytało, skąd wiedziałeś, że highlightedjest własnością na UIButton. Odpowiedź jest taka, że ​​jest to właściwość UIControl, z której dziedziczy UIButton.
Adam Johns

25

Zastąp podświetloną zmienną. Dodanie @IBInspectablesprawia, że ​​edytujesz podświetlony kolor tła w serii ujęć, który również jest fajny.

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

bardziej kompaktowe rozwiązanie (na podstawie odpowiedzi @ 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()
    }
}

Jeśli nie chcesz przesłonić, jest to zaktualizowana wersja odpowiedzi @ 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 to zastąpi to Podświetlone we wszystkich przyciskach w Twojej aplikacji, co moim zdaniem nie jest dobrym rozwiązaniem. pójdę z odpowiedzią Timura.
Usama bin Attique,

13

Rozszerzenie UIButton ze składnią 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)
    }}

Używaj go jak:

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

Oryginalna odpowiedź: https://stackoverflow.com/a/30604658/3659227


10

Oto podejście w Swift, wykorzystujące rozszerzenie UIButton, aby dodać IBInspectable, o nazwie highlightedBackgroundColor. Podobny do podklasy, bez wymagania podklasy.

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

Mam nadzieję, że to pomoże.


1
W przypadku wersji 2.0 należy zaktualizować wywołanie obiektu objc_setAssociatedObject, aby użyć wyliczenia: objc_setAssociatedObject (self, & NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Eli Burke

Zdecydowanie najlepszy sposób w Swift, jeśli chcesz zachować wszystko w Storyboard.
davidethell

1
Wolę używać podklasy zamiast rozszerzenia, ponieważ wpłynie to na całą aplikację
Hossam Ghareeb 27.04.16


9

Moje najlepsze rozwiązanie dla Swift 3+ bez podklas.

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

Dzięki temu rozszerzeniu można łatwo zarządzać kolorami dla różnych stanów i automatycznie wyciszy Twój normalny kolor, w przypadku braku wyróżnionego koloru.

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

4

AKTUALIZACJA:

Użyj biblioteki UIButtonBackgroundColor Swift.

STARY:

Użyj pomocników poniżej, aby utworzyć obraz o wymiarach 1 x 1 x 1 piksel z kolorem wypełnienia w skali szarości:

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

lub kolor wypełnienia RGB:

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

Następnie użyj tego, imageaby ustawić obraz tła przycisku:

[button setBackgroundImage:image forState:UIControlStateNormal];

Pomocnicy

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

Uwaga: ACUjest prefiksem klasy mojej biblioteki statycznej Cocoa Touch o nazwie Acani Utilities, gdzie AC oznacza Acani, a U oznacza Utilities.


4

Spróbuj tego !!!!

Dla zdarzenia TouchedDown ustaw jeden kolor, a dla TouchUpInside ustaw drugi.

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

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

2
Pracował dla mnie. Musiałem tylko dodać, - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {aby upewnić się, że kolor nie pozostanie włączony, gdy użytkownik przypadkowo wyciągnie palec z przycisku.
SudoPlz

4

Podklasuj przycisk UIB i dodaj właściwości, które można sprawdzić, dla wygodnego użycia (napisane w 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

Możesz podklasować UIButton i zrobić niezły 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

Uwagi (To jest przykład, wiem, że są problemy i oto kilka)

Użyłem NSMutableDictionay do przechowywania UIColor dla każdego stanu, muszę zrobić nieprzyjemną konwersję tekstu dla klucza, ponieważ UIControlState nie jest ładną prostą int. Jeśli to tam możesz zainicjować tablicę z tyloma obiektami i użyć stanu jako indeksu.

Z tego powodu wielu ma trudności z np. Wybraniem i wyłączeniem przycisku, potrzeba nieco więcej logiki.

Kolejny problem polega na tym, że jeśli próbujesz ustawić wiele kolorów jednocześnie, nie próbowałem za pomocą przycisku, ale jeśli możesz to zrobić, może nie działać

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

Zakładam, że to StoryBoard, nie ma init, initWithFrame, więc dodaj je, jeśli ich potrzebujesz.


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 , dzięki @Maverick


3

Detale

  • Xcode 11.1 (11A1027), Swift 5

Rozwiązanie

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

Stosowanie

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

2

Spróbuj tego, jeśli masz obraz:

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

lub sprawdź, czy showsTouchWhenHighlightedto ci wystarczy.


Próbowałem grać z programami TouchThenWhighlighted, ale to nie pomogło. Nie chcę używać setBackgroundImage: forState :. W rzeczywistości próbowałem użyć koloru tła, aby nie używać żadnego obrazu.
MartinMoizard


2

Aby rozwiązać ten problem, stworzyłem kategorię do obsługi backgroundColorstanów za pomocą UIButtons:
ButtonBackgroundColor-iOS

Możesz zainstalować kategorię jako kapsuła .

Łatwy w użyciu z Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

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

Jeszcze łatwiejszy w użyciu dzięki Swift :

import ButtonBackgroundColor

...

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

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

Polecam zaimportować kapsułę z:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Korzystanie z use_frameworks! w Podfile ułatwia korzystanie ze swoich strąków dzięki Szybkiemu i celowi-C.

WAŻNY

Napisałem też post na blogu z dodatkowymi informacjami.


2
class CustomButton: UIButton {

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

}


1

Spróbuj tintColor:

_button.tintColor = [UIColor redColor];

Czy na pewno jest to powiązane w IB? Co otrzymasz, jeśli to zrobisz NSLog(@"%@", _button);?
jjv360

1
To nie zadziała, jeśli używasz UIButtonTypeCustom.
JaredH

1

Oto kod w Swift, aby wybrać stan przycisku:

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

Przykład:

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

1

Upuść go i możesz zacząć:
* Proerty można ustawić w IB, a jeśli nie zostanie ustawione podświetlone tło, tło nie zmieni się po naciśnięciu

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

Poniższe UIIImagerozszerzenie wygeneruje obiekt obrazu o określonym parametrze koloru.

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

Przykładowe użycie przycisku można zastosować do obiektu przycisku jako:

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

proste jest użycie TYLKO tego rozszerzenia 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)
        }
    }

}

i użyj tego

 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

w Swift 5

Dla tych, którzy nie chcą używać kolorowego tła, aby pobić wybrany stan

Po prostu możesz pokonać problem za pomocą instrukcji #Selector i if, aby łatwo zmienić kolory UIButton dla każdego stanu

Na przykład:

    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

    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.