it-swarm.com.de

Wie ändere ich die Hintergrundfarbe eines hervorgehobenen UIButton?

Irgendwann in meiner App ist UIButton markiert (z. B. wenn ein Benutzer seinen Finger auf der Schaltfläche hat) und ich muss die Hintergrundfarbe ändern, während die Schaltfläche markiert ist (während der Finger des Benutzers markiert ist) noch auf dem Knopf).

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 funktioniert. Ich habe auch versucht, -setNeedsDisplay aufzurufen, nachdem ich die Farbe geändert habe, es hatte keine Wirkung.

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

223
MartinMoizard

Sie können die UIButton -Methode von setHighlighted überschreiben.

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
    }
}
391
Thomas Decaux

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

Option 1:

Zum Erfassen werden zwei Ereignisse benötigt, UIControlEventTouchDown, wenn der Benutzer die Taste drückt. UIControlEventTouchUpInside und UIControlEventTouchUpOutside werden aktiviert, wenn sie die Taste 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:

Gibt ein Bild aus der gewünschten Markierungsfarbe zurück. 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 hervorgehobenen Zustand der Schaltfläche:

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

Es ist nicht erforderlich, highlighted als berechnete Eigenschaft zu überschreiben. Sie können Property Observer verwenden, um die Ä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
    }
}
92

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
        }
    }
45
Jake Hall

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.

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)
    }
}
44
Giordano Scalzo

Markierte Variable überschreiben. Wenn Sie @IBInspectable hinzufügen, können Sie die markierte backgroundColor im Storyboard bearbeiten, was ebenfalls praktisch 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
        }
    }
}
23
mash

eine kompaktere Lösung (basierend auf @ aleksejs-mjaliks Antwort):

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 der Antwort von @ 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)
  }
}
17

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 folgt:

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

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

12
Maverick

Hier ist ein Ansatz in Swift, bei dem eine UIButton-Erweiterung zum Hinzufügen eines IBInspectable mit dem Namen highlightedBackgroundColor verwendet wird. Ähnlich wie 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.

10
Fostah

Sie können diese Kategorie verwenden, um die Methode setBackgroundColor: forState: hinzuzufügen.

https://github.com/damienromito/UIButton-setBackgroundColor-forState-

9
Damien Romito

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 Status zu verwalten, und es wird Ihre normale Farbe automatisch ausgeblendet, falls keine hervorgehobene Farbe bereitgestellt wird.

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

Unterklassen 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
            }
        }
    }
}
4
Bence Pattogato

Versuche dies !!!!

Stellen Sie für TouchedDown-Ereignis eine Farbe und für TouchUpInside die andere ein.

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

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

AKTUALISIEREN:

Verwenden Sie die Bibliothek IButtonBackgroundColor Swift.

ALT:

Verwenden Sie die folgenden Hilfsprogramme, um ein 1 x 1 Pixel großes Bild mit einer Graustufen-Fü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 dann image, 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: ACU ist das Klassenpräfix meiner Cocoa Touch Static Library mit dem Namen Acani Utilities, wobei AC für Acani und U für Utilities steht.

4
ma11hew28

Auf Storyboard ...

Sie können die Einstellungen für einzelne UIButton-Status ändern. Wählen Sie beispielsweise "Ausgewählt" und Sie können dann die Textfarbe für diesen Status ändern.

So ändern Sie den Hintergrund, wenn der UIButton markiert ist:

  1. Wählen Sie die gewünschte Schaltfläche im Storyboard.
  2. Wählen Sie die gewünschte Statuskonfiguration. Wählen Sie für Ihren Fall "Hervorgehoben". How to change the state configuration in Storyboard.
  3. Ändern Sie die Hintergrundfarbe. Sie können jetzt mit Schritt 2 zu anderen Status navigieren und die Hintergrundfarbe für diesen Status angeben. How to change the background color in Storyboard.
2
Josh Wolff

Sie können den UIButton in Unterklassen unterteilen und einen Nice 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

Notizen (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 Staat zu speichern. Ich muss eine fiese Textkonvertierung für den Schlüssel durchführen, da der UIControlState kein Nice straight Int ist. Wenn es möglich wäre, ein Array mit so vielen Objekten zu initialisieren und den Status als Index zu verwenden.

Aus diesem Grund haben Sie viele Schwierigkeiten mit z. eine ausgewählte & deaktivierte Schaltfläche, etwas mehr Logik ist 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, das ist StoryBoard, es gibt kein Init, initWithFrame, also füge sie hinzu, wenn du sie brauchst.

2
Recycled Steel

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

2
Stunner
class CustomButton: UIButton {

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

}
2
evya

Um dieses Problem zu lösen, habe ich eine Kategorie erstellt, um backgroundColor Zustände mit UIButtons zu behandeln:
ButtonBackgroundColor-iOS

Sie können die Kategorie als Pod installieren.

Einfach zu bedienen mit Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

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

Noch einfacher zu bedienen mit Swift :

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 mehr Informationen geschrieben.

2
Gabriel.Massana

Versuchen Sie dies, wenn Sie ein Bild haben:

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

oder sehen Sie, ob showsTouchWhenHighlighted für Sie ausreicht.

2
Siby

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

Mit CocoaPods zum Podfile hinzufügen

pod "UIButtonSetBackgroundColorForState"

Swift

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

Ziel-C

[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
2
swordray


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
shoe

Hier ist der Code in Swift, der für den Schaltflächenstatus ausgewählt werden soll:

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)
1
Mike Zriel

Die Erweiterung UIIImage 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 Beispielverwendung 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)
1
manoj kumar

Versuchen Sie tintColor:

_button.tintColor = [UIColor redColor];
1
jjv360

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
Elita

wenn Sie nicht überschreiben möchten, legen Sie einfach zwei Aktionen fest

0
Roman Bambura