ios - tag - Wie ändere ich die Hintergrundfarbe einer UIButton, während sie hervorgehoben ist?




title tag wordpress (18)

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

Ich habe Folgendes versucht:

_button.backgroundColor = [UIColor redColor];

Aber es funktioniert nicht. Die Farbe bleibt gleich. Ich habe das gleiche Stück Code ausprobiert, wenn die Schaltfläche nicht hervorgehoben ist und es funktioniert. Ich versuchte auch -setNeedsDisplay nach dem Ändern der Farbe zu -setNeedsDisplay , es hatte keine Wirkung.

Wie erzwinge ich mit der Taste die Hintergrundfarbe?


Es funktioniert gut mit swift 3, um Schaltflächenhintergrund und Schaltflächentitelfarbe beim Klicken zu ändern:

@IBAction func btnColorChange(_ sender: UIButton) {

   sender.backgroundColor = .red
   sender.setTitleColor(.white, for: .normal)
}

Überschriebene Variable überschreiben Durch Hinzufügen von @IBInspectable Sie die hervorgehobene backgroundColor im Storyboard bearbeiten, was ebenfalls @IBInspectable 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
        }
    }
}

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

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

Es besteht keine Notwendigkeit, die als berechnete Eigenschaft highlighted zu überschreiben. Sie können die Objektbeobachtung verwenden, um eine Hintergrundfarbänderung auszulösen:

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

Schnell 4

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

Hier ist der Code in Swift, um den Status der Schaltfläche auszuwählen:

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)

Hier ist ein Ansatz in Swift, der mithilfe einer UIButton-Erweiterung ein IBInspectable namens highlightedBackgroundColor hinzufügt. Ähnlich wie Unterklassen, ohne eine Unterklasse zu benötigen.

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.


Ich habe eine UIButton-Unterklasse, STAButton , open- STAButton , um diese klaffende Funktionalität zu füllen. Verfügbar unter der MIT-Lizenz. Funktioniert für iOS 7+ (ich habe nicht mit älteren iOS-Versionen getestet).


In swift können Sie den Zugriffsmechanismus der markierten (oder ausgewählten) Eigenschaft außer Kraft setzen, statt die Methode setHighlighted zu überschreiben

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

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 die normale Farbe wird automatisch ausgeblendet, falls die hervorgehobene Farbe nicht zur Verfügung steht.

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

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

Sie können die UIButton ableiten und einen schönen forState erstellen.

FarbButton.h

#import <UIKit/UIKit.h>

@interface colourButton : UIButton

-(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;

@end

FarbButton.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 ein NSMutableDictionay verwendet, um die UIColor für jeden Staat zu speichern, ich muss eine böse Textkonvertierung für den Schlüssel tun, da der UIControlState kein nettes straight Int ist. Wenn es möglich wäre, ein Array mit so vielen Objekten zu initiieren und den Status als Index zu verwenden.

Aus diesem Grund haben Sie viele Schwierigkeiten mit zB einer ausgewählten & deaktivierten Taste, etwas mehr Logik wird benötigt.

Ein anderes Problem ist, wenn Sie versuchen, mehrere Farben gleichzeitig einzustellen, habe ich nicht mit einer Taste 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 keine init, initWithFrame, also fügen Sie sie hinzu, wenn Sie sie brauchen.



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

Sie können die Kategorie als pod installieren.

Einfach mit Objective-C zu verwenden

@property (nonatomic, strong) UIButton *myButton;

...

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

Noch einfacher mit Swift zu verwenden :

import ButtonBackgroundColor

...

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

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

Ich empfehle dir, den Pod mit zu importieren:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Verwenden von use_frameworks! in Ihrem Podfile macht es einfacher, Ihre Pods mit Swift und Objective-C zu verwenden.

WICHTIG

somethingaboutios.wordpress.com/2016/02/09/…


Unterhalb der UIIImage Erweiterung wird ein Bildobjekt mit dem angegebenen UIIImage erzeugt.

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)

Versuche dies !!!!

Für TouchedDown Event setzen Sie 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];    
}

Versuchen Sie tintColor :

_button.tintColor = [UIColor redColor];

Wenn Sie nicht überschreiben, setzen Sie einfach zwei Aktionen touchDown touchUpInside


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

Schnell 2:

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

Schnell 3/4 + :

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




uibutton