Wie ändere ich die Hintergrundfarbe eines UIButton, während er hervorgehoben ist?

235

Irgendwann in meiner App habe ich eine Markierung UIButton(zum Beispiel wenn ein Benutzer seinen Finger auf der Schaltfläche hat) und ich muss die Hintergrundfarbe ändern, während die Schaltfläche hervorgehoben ist (also während der Finger des Benutzers noch auf der Schaltfläche ist). .

Ich habe folgendes versucht:

_button.backgroundColor = [UIColor redColor];

Aber es funktioniert nicht. Die Farbe bleibt gleich. Ich habe den gleichen Code ausprobiert, wenn die Schaltfläche nicht markiert ist und einwandfrei funktioniert. Ich habe auch versucht, -setNeedsDisplaynach dem Ändern der Farbe anzurufen, es hatte keine Auswirkung.

Wie kann man die Schaltfläche zwingen, die Hintergrundfarbe zu ändern?

MartinMoizard
quelle

Antworten:

411

Sie können außer Kraft setzen UIButton‚s - setHighlightedMethode.

Ziel c

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

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

Swift 3.0 und Swift 4.1

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.black : UIColor.white
    }
}
Thomas Decaux
quelle
Ja. Es ist eine nette Art, dies zu tun. Weil Sie mehrere ähnliche Schaltflächen definieren können.
Paul Brewczynski
3
Nur eine Frage für Neulinge, wo würden Sie diese Schaltflächenmethode unterordnen? Wenn ich in einem Ansichts-Controller eine Schaltfläche mit dem Namen ConversionViewController habe, wie würde ich die Schaltfläche so einrichten, dass die Hintergrundfarbe beim Hervorheben oder Tippen geändert wird? Würde ich das setHIghlighted im COnversionViewController unterordnen?
Beanno1116
Es gibt also ein Problem mit dieser Antwort, das ich gefunden habe. Wenn Sie möchten, dass dieselbe Farbe verfügbar ist, wenn Sie die Schaltfläche auswählen, wird setHighlighted nach setSelected aufgerufen und überschreibt somit alle ausgewählten Stile, die Sie haben. Die obige Lösung könnte besser sein, wenn Sie auch die Schaltfläche auswählen möchten
HaloZero
3
@YakivKovalskiy Unter der Annahme, dass Sie eine Unterklasse verwenden, können Sie zwei UIColor-Eigenschaften hinzufügen, z. B. normalBackground und hervorragender Hintergrund, und dann self.backgroundColor = normalBackground oder hervorgehobener Hintergrund entsprechend zuweisen. Vergessen Sie nicht, eine Init-Methode hinzuzufügen, um die Verwendung zu vereinfachen, z. B. initWithBackground: hervorgehobenBackground:
SK.
2
Schöne Lösung, nur ein Vorschlag:backgroundColor = isHighlighted ? .lightGray : .white
Fantini
298

Ich bin mir nicht sicher, ob diese Art von Lösung das ist, wonach Sie suchen, oder ob sie zu Ihrer allgemeinen Entwicklungslandschaft passt, aber das erste, was ich versuchen würde, wäre, die Hintergrundfarbe der Schaltfläche im touchDown-Ereignis zu ändern.

Option 1:

Sie würden zwei Ereignisse benötigen, um erfasst zu werden. UIControlEventTouchDown ist für den Fall vorgesehen, dass der Benutzer die Taste drückt. UIControlEventTouchUpInside und UIControlEventTouchUpOutside werden verwendet, wenn sie die Schaltfläche loslassen, um sie in den normalen Zustand zurückzusetzen

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:

Geben Sie ein Bild zurück, das aus der gewünschten Hervorhebungsfarbe erstellt wurde. Dies könnte auch eine Kategorie sein.

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

und ändern Sie dann den markierten Status der Schaltfläche:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];
Tim
quelle
3
Fügen Sie UIControlEventTouchUpOutside und UIControlEventTouchCancel zu buttonHighlight: Ereignisliste hinzu, und es funktioniert immer.
Evgen Bodunov
Option zwei ist die beste, die ich bisher gefunden habe. Ich denke jedoch, dass Storyboards in diesem Fall ihre Vorteile haben!
Jack Solomon
Die Antwort von Thomas ist besser und das benutze ich auch
Van Du Tran
26
Wenn Sie layer.cornerRadiusOption 2 verwenden und verwenden, müssen Sie sicherstellen clipsToBounds, dass true festgelegt ist, damit auch die Bildecken abgerundet werden.
Himmel
3
Wenn jemand vorbeischaut
winterfest
94

Es besteht keine Notwendigkeit zum Überschreiben highlighted als berechnete Eigenschaft . Sie können den Eigenschaftsbeobachter verwenden, um eine Änderung der Hintergrundfarbe auszulösen:

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
quelle
1
Ich habe noch nie solche Funktionen verwendet. Können Sie erklären, wohin das führt? Ist es in der IBAction buttonPress-Funktion oder in der viewDidLoad?
Dave G
Was ist, wenn ich mehrere UIButtons mit unterschiedlichen Farben habe?
Slavcho
6
@ Dave G, Sie erstellen eine neue Unterklasse von UIButton, indem Sie darauf klicken File>New>File>Cocoa Touch Classund diese festlegen subclass of UIButton. Benennen Sie die Datei beispielsweise CustomButton, die sowohl zum Dateinamen als auch zum Klassennamen wird. Fügen Sie in diese Datei den override var highlightedoben gezeigten Code ein. Stellen Sie im letzten Schritt den UIButton im Interface Builder so ein, dass er diese CustomButtonUnterklasse verwendet, indem Sie auf die Seite "Eigenschaften" gehen, auf der "Benutzerdefinierte Klasse" steht und ein Dropdown-Feld angezeigt wird. In grauen Buchstaben wird "UIButton" angezeigt. In der Dropdown-Liste sollte CustomButton angezeigt werden. Wählen Sie diese Option aus, und die Schaltfläche ist jetzt in Unterklassen unterteilt.
James Toomey
Warum niemand erwähnt hat, dass der Setter nur aufgerufen wird, wenn Sie auf die Schaltfläche tippen, aber nicht während des anfänglichen Layouts! Standardmäßig gibt es also keine Farbe, bis Sie die Taste berühren.
Dmitrii
Damit es funktioniert, müssen Sie auch isHighlighted = falseirgendwo am Anfang explizit aufrufen (zum Beispiel bei der Initialisierung).
Dmitrii
48

Eine praktische generische Erweiterung 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)
    }
}
Giordano Scalzo
quelle
45

In Swift können Sie den Accessor der hervorgehobenen (oder ausgewählten) Eigenschaft überschreiben, anstatt die setHighlighted-Methode zu überschreiben

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }
Jake Hall
quelle
Das funktioniert völlig, aber ich bin verwirrt, wie Sie das herausfinden konnten? Die Parameter sind, soweit ich das beurteilen kann, nicht in der Dokumentation oder in UIButton.h enthalten.
Shimizu
1
Dies ist die schnelle Syntax, die das Verhalten des Überschreibens von setHightlighted in Ziel c emuliert. Siehe Dokumentation zu berechneten Eigenschaften hier developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Jake Hall
11
In Kürze könnten Sie didSet
Dam
1
Ich habe ein Beispiel mit dem Property Observer hinzugefügt: stackoverflow.com/a/29186375/195173 .
Aleksejs Mjaliks
Ich denke, @shimizu fragte, woher wusstest du, dass highlightedes sich um eine Immobilie auf UIButton handelt? Die Antwort ist, dass es sich um eine Eigenschaft in UIControl handelt, von der UIButton erbt.
Adam Johns
25

Markierte Variable überschreiben. Durch Hinzufügen können @IBInspectableSie die hervorgehobene Hintergrundfarbe im Storyboard bearbeiten, was ebenfalls hilfreich ist.

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
        }
    }
}
Maische
quelle
20

eine kompaktere Lösung (basierend auf der Antwort von @ 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()
    }
}

Wenn Sie nicht überschreiben möchten, ist dies eine aktualisierte Version von @ timur-bernikowichs Antwort ( 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
quelle
@FedericoZanetello dies wird überschrieben isHighlighted in allen Schaltflächen in Ihrer App, was meiner Meinung nach keine gute Lösung ist. Ich werde mit Timurs Antwort gehen.
Usama bin Attique
13

UIButton-Erweiterung mit Swift 3+ -Syntax :

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

Verwenden Sie es wie:

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

Ursprüngliche Antwort: https://stackoverflow.com/a/30604658/3659227

Einzelgänger
quelle
10

Hier ist ein Ansatz in Swift, bei dem eine UIButton-Erweiterung verwendet wird, um eine IBInspectable mit dem Namen hervorgehobenBackgroundColor hinzuzufügen. Ähnlich wie bei Unterklassen, ohne dass eine Unterklasse erforderlich ist.

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

Ich hoffe das hilft.

Fostah
quelle
1
Für Swift 2.0 müssen Sie den Aufruf von objc_setAssociatedObject aktualisieren, um eine Aufzählung zu verwenden: objc_setAssociatedObject (self, & NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Eli Burke
Auf jeden Fall der beste Weg in Swift, wenn Sie alles im Storyboard behalten möchten.
Davidethell
1
Ich bevorzuge die Verwendung der Unterklasse ohne Erweiterung, da dies die gesamte App
betrifft
9

Meine beste Lösung für Swift 3+ ohne Unterklassen.

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

Mit dieser Erweiterung ist es einfach, Farben für verschiedene Zustände zu verwalten, und Ihre normale Farbe wird automatisch ausgeblendet, falls keine hervorgehobene Farbe bereitgestellt wird.

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

AKTUALISIEREN:

Verwenden Sie die UIButtonBackgroundColor Swift-Bibliothek.

ALT:

Verwenden Sie die folgenden Helfer, um ein 1 x 1 Pixel großes Bild mit einer Graustufenfüllfarbe zu erstellen:

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

oder eine RGB-Füllfarbe:

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

Verwenden Sie diese imageOption, um das Hintergrundbild der Schaltfläche festzulegen:

[button setBackgroundImage:image forState:UIControlStateNormal];

Helfer

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

Hinweis: ACUist das Klassenpräfix meiner statischen Cocoa Touch-Bibliothek mit dem Namen Acani Utilities, wobei AC für Acani und U für Utilities steht.

ma11hew28
quelle
4

Versuche dies !!!!

Für TouchedDown Event Set Eine Farbe und für TouchUpInside die andere.

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

- (IBAction)touchUpInside:(id)sender {
    NSLog(@"TouchUpInside");
    btn1.backgroundColor=[UIColor whiteColor];    
}
Karan Alangat
quelle
2
Hat für mich gearbeitet. Ich musste nur hinzufügen - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {, um sicherzustellen, dass die Farbe nicht eingeschaltet bleibt, wenn der Benutzer versehentlich seinen Finger vom Knopf zieht.
SudoPlz
4

Unterklassifizieren Sie den UIButton und fügen Sie überprüfbare Eigenschaften für eine bequeme Verwendung hinzu (geschrieben 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
            }
        }
    }
}
Bence Pattogato
quelle
3

Sie können den UIButton unterordnen und einen schönen forState erstellen.

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

Anmerkungen (Dies ist ein Beispiel, ich weiß, dass es Probleme gibt und hier sind einige)

Ich habe einen NSMutableDictionay verwendet, um die UIColor für jeden Status zu speichern. Ich muss eine unangenehme Textkonvertierung für den Schlüssel durchführen, da der UIControlState kein netter Straight Int ist. Wenn Sie ein Array mit so vielen Objekten initiieren und den Status als Index verwenden könnten.

Aus diesem Grund haben Sie viele Schwierigkeiten, z. B. mit einer ausgewählten und deaktivierten Schaltfläche. Es ist etwas mehr Logik erforderlich.

Ein weiteres Problem ist, wenn Sie versuchen, mehrere Farben gleichzeitig einzustellen. Ich habe es nicht mit einer Schaltfläche versucht, aber wenn Sie dies tun können, funktioniert es möglicherweise nicht

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

Ich habe angenommen, dass dies StoryBoard ist, es gibt kein init, initWithFrame, also füge sie hinzu, wenn du sie brauchst.

Recycelter Stahl
quelle
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 , danke @Maverick

dengST30
quelle
3

Einzelheiten

  • Xcode 11.1 (11A1027), Swift 5

Lösung

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

Verwendung

button.setBackground(.green, for: .normal)
Wassili Bodnarchuk
quelle
2

Versuchen Sie dies, wenn Sie ein Bild haben:

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

oder sehen Sie, ob showsTouchWhenHighlightedes Ihnen reicht.

Siby
quelle
Ich habe versucht, mit ShowsTouchWhenHighlighted herumzuspielen, aber es hat nicht geholfen. Ich möchte setBackgroundImage: forState: nicht verwenden. Ich habe tatsächlich versucht, mit backgroundColor kein Bild zu verwenden.
MartinMoizard
2

Ich habe eine UIButton-Unterklasse, STAButton , als Open-Source-Lösung ausgewählt , um diese Lücke zu schließen. Verfügbar unter der MIT-Lizenz. Funktioniert für iOS 7+ (ich habe nicht mit älteren iOS-Versionen getestet).

Stunner
quelle
2

Um dieses Problem zu lösen, habe ich eine Kategorie erstellt, backgroundColormit der Zustände behandelt werden können UIButtons:
ButtonBackgroundColor-iOS

Sie können die Kategorie als Pod installieren .

Einfache Verwendung mit Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

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

Noch einfacher mit Swift zu bedienen :

import ButtonBackgroundColor

...

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

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

Ich empfehle Ihnen, den Pod zu importieren mit:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Use_frameworks verwenden! in Ihrem Podfile erleichtert die Verwendung Ihrer Pods mit Swift und Objective-C.

WICHTIG

Ich habe auch einen Blog-Beitrag mit weiteren Informationen geschrieben.

Gabriel.Massana
quelle
2
class CustomButton: UIButton {

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

}
Evya
quelle
2

Verwenden Sie https://github.com/swordray/UIButtonSetBackgroundColorForState

Mit CocoaPods zum Podfile hinzufügen

pod "UIButtonSetBackgroundColorForState"

Schnell

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

Ziel c

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
Schwertkampf
quelle
1

Versuchen Sie tintColor:

_button.tintColor = [UIColor redColor];
jjv360
quelle
Sind Sie sicher, dass es in IB verknüpft ist? Was bekommen Sie, wenn Sie das tun NSLog(@"%@", _button);?
JJV360
1
Dies funktioniert nicht, wenn Sie a verwenden UIButtonTypeCustom.
JaredH
1

Hier ist der Code in Swift, den Sie für den Schaltflächenstatus auswählen können:

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

Beispiel:

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


Legen Sie es ab und Sie können loslegen : * Die Eigenschaft kann in IB eingestellt werden. Wenn kein hervorgehobener Hintergrund festgelegt ist, ändert sich der Hintergrund nicht, wenn Sie darauf drücken

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
        }
    }
}
Schuh
quelle
1

Die folgende UIIImageErweiterung generiert ein Bildobjekt mit dem angegebenen Farbparameter.

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

Eine beispielhafte Verwendung für eine Schaltfläche kann für das Schaltflächenobjekt wie folgt angewendet werden:

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

Einfach ist, dass Sie NUR diese UIButton-Erweiterung verwenden

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

}

und benutze dies

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

Wenn Sie nicht überschreiben möchten, setzen Sie einfach zwei Aktionen: touchDown touchUpInside

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

in Swift 5

Für diejenigen, die keinen farbigen Hintergrund verwenden möchten, um den ausgewählten Status zu übertreffen

Sie können das Problem einfach lösen, indem Sie die Anweisung #Selector & if verwenden, um die UIButton-Farben für jeden Status einfach und individuell zu ändern

Beispielsweise:

    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
quelle