Comment changer la couleur de fond d'un UIButton pendant qu'il est surligné?
à un moment donné dans mon application j'ai mis en surbrillance UIButton
(par exemple quand un utilisateur a son doigt sur le bouton) et je dois changer la couleur de fond pendant que le bouton est mis en surbrillance (donc pendant que le doigt de l'utilisateur est encore sur le bouton).
j'ai essayé la suivante:
_button.backgroundColor = [UIColor redColor];
mais ça ne marche pas. La couleur reste la même. J'ai essayé le même morceau de code quand le bouton n'est pas surligné et il fonctionne très bien. J'ai aussi essayé d'appeler -setNeedsDisplay
après avoir changé la couleur, il n'a pas eu d'effet.
comment forcer le bouton pour changer la couleur de fond?
27 réponses
vous pouvez remplacer UIButton
's setHighlighted
méthode.
Objectif-C
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
self.backgroundColor = UIColorFromRGB(0x387038);
} else {
self.backgroundColor = UIColorFromRGB(0x5bb75b);
}
}
Swift 3.0 et Swift 4.1
override open var isHighlighted: Bool {
didSet {
backgroundColor = isHighlighted ? UIColor.black : UIColor.white
}
}
Je ne suis pas sûr que ce genre de solution résolve ce que vous recherchez, ou s'adapte à votre paysage de développement général, mais la première chose que je voudrais essayer serait de changer la couleur de fond du bouton sur l'événement touchDown.
Option 1:
vous auriez besoin de deux événements pour être capturé, UIControlEventTouchDown serait pour lorsque l'utilisateur appuie sur le bouton. L'uicontreleventtouchupinside et L'Uicontreleventtouchupoutside seront quand ils relâchez le bouton pour revenir à l'état normal
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setFrame:CGRectMake(10.0f, 10.0f, 100.0f, 20.f)];
[myButton setBackgroundColor:[UIColor blueColor]];
[myButton setTitle:@"click me:" forState:UIControlStateNormal];
[myButton setTitle:@"changed" forState:UIControlStateHighlighted];
[myButton addTarget:self action:@selector(buttonHighlight:) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(buttonNormal:) forControlEvents:UIControlEventTouchUpInside];
Option 2:
retourner une image faite à partir de la couleur de surbrillance que vous voulez. Cela pourrait aussi être une catégorie.
+ (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;
}
et ensuite changer l'état surligné du bouton:
[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];
il n'est pas nécessaire de remplacer highlighted
comme bien calculé. Vous pouvez utiliser la propriété observer pour déclencher le changement de couleur de fond:
override var highlighted: Bool {
didSet {
backgroundColor = highlighted ? UIColor.lightGrayColor() : UIColor.whiteColor()
}
}
Swift 4
override var isHighlighted: Bool {
didSet {
backgroundColor = isHighlighted ? UIColor.lightGray : UIColor.white
}
}
dans swift, vous pouvez outrepasser l'accessor de la propriété highlighted (ou selected) plutôt que la méthode setHighlighted
override var highlighted: Bool {
get {
return super.highlighted
}
set {
if newValue {
backgroundColor = UIColor.blackColor()
}
else {
backgroundColor = UIColor.whiteColor()
}
super.highlighted = newValue
}
}
une extension générique pratique dans 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)
}
}
remplace la variable surlignée.
L'ajout de @IBInspectable
vous permet d'éditer la couleur de fond en surbrillance dans le storyboard, ce qui est aussi astucieux.
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
}
}
}
une solution plus compacte (basée sur @aleksejs-mjaliks réponse):
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()
}
}
extension UIButton avec Swift 3+ syntaxe:
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)
}}
utiliser comme:
YourButton.setBackgroundColor(color: UIColor.white, forState: .highlighted)
Réponse Originale: https://stackoverflow.com/a/30604658/3659227
vous pouvez utiliser cette catégorie qui ajoute la méthode setBackgroundColor: forState:
https://github.com/damienromito/UIButton-setBackgroundColor-forState -
Voici une approche dans Swift, en utilisant une extension UIButton pour ajouter un IBInspectable, appelé highlightedBackgroundColor. Semblable au sous-classement, sans exiger de sous-classe.
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
}
}
}
}
}
j'espère que cela aidera.
Mon meilleur solution pour les "151930920 Swift" 3+ sans sous-classement.
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)
}
}
avec cette extension, il est facile de gérer les couleurs pour différents états et il se décolorera votre couleur normale automatiquement au cas où la couleur mise en évidence n'est pas fournie.
button.setBackgroundColor(.red, for: .normal)
mise à jour:
utilisez la UIButtonBackgroundColor bibliothèque Swift.
OLD:
utilisez les helpers ci-dessous pour créer une image 1 px x 1 px avec une couleur de remplissage en échelle de gris:
UIImage *image = ACUTilingImageGray(248/255.0, 1);
ou une couleur de remplissage RVB:
UIImage *image = ACUTilingImageRGB(253/255.0, 123/255.0, 43/255.0, 1);
ensuite, utilisez ce image
pour régler l'image de fond du bouton:
[button setBackgroundImage:image forState:UIControlStateNormal];
Helpers
#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;
}
Note: ACU
est le préfixe de classe de ma bibliothèque statique Cocoa Touch appelée Acani Utilities, où AC est pour Acani, et U pour Utilities.
essayez ça !!!!
pour L'événement TouchedDown définit une couleur et pour le TouchUpInside définit l'autre.
- (IBAction)touchedDown:(id)sender {
NSLog(@"Touched Down");
btn1.backgroundColor=[UIColor redColor];
}
- (IBAction)touchUpInside:(id)sender {
NSLog(@"TouchUpInside");
btn1.backgroundColor=[UIColor whiteColor];
}
sous-classe L'UIButton et ajouter des propriétés inspectables pour une utilisation Commode (écrit dans 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
}
}
}
}
essayez ceci si vous avez une image:
-(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
ou voyez si showsTouchWhenHighlighted
vous suffit.
vous pouvez classer L'UIButton et faire une belle 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
Notes (C'est un exemple, je sais qu'il y a des problèmes et voici quelques-uns)
j'ai utilisé un Nsmutabldictionay pour stocker L'UIColor pour chaque État, je dois faire une conversion de texte désagréable pour la clé comme L'UIControlState n'est pas une belle ligne droite Int. Si c'est là que vous pouvez insérer un tableau avec autant d'objets et utiliser l'État comme un index.
pour cette raison, vous avez beaucoup de difficultés avec par exemple un bouton sélectionné et désactivé, un peu plus de logique est nécessaire.
un Autre problème est que si vous essayez de définir plusieurs couleurs en même temps, je n'ai pas essayé avec un bouton, mais si vous pouvez faire cela, il peut ne pas fonctionner
[btn setBackgroundColor:colour forState:UIControlStateSelected & UIControlStateHighlighted];
j'ai supposé que c'est StoryBoard, il n'y a pas init, initWithFrame donc les ajouter si vous en avez besoin.
pour résoudre ce problème j'ai créé une catégorie pour gérer les États backgroundColor
avec UIButtons
:
ButtonBackgroundColor-iOS
vous pouvez installer la catégorie comme un pod .
facile à utiliser avec objectif-c
@property (nonatomic, strong) UIButton *myButton;
...
[self.myButton bbc_backgroundColorNormal:[UIColor redColor]
backgroundColorSelected:[UIColor blueColor]];
encore plus facile à utiliser avec Swift :
import ButtonBackgroundColor
...
let myButton:UIButton = UIButton(type:.Custom)
myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())
je vous recommande d'importer la gousse avec:
platform :ios, '8.0'
use_frameworks!
pod 'ButtonBackgroundColor', '~> 1.0'
en utilisant use_frameworks! dans votre Podfile rend plus facile d'utiliser vos gousses avec Swift et objectif-C.
IMPORTANT
j'ai aussi écrit un billet de Blog avec plus d'informations.
voici le code dans Swift pour sélectionner l'état du bouton:
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;
}
exemple:
self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)
Drop et vous êtes bon pour aller:
* proerty peut être défini dans IB, et si aucun fond en surbrillance n'est défini, le fond ne changera pas lorsqu'on appuie sur
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
}
}
}
au-dessous de UIIImage
l'extension générera l'objet image avec le paramètre de couleur spécifié.
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
}
}
un exemple d'usage pour un bouton peut être appliqué pour l'objet bouton comme:
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)
class CustomButton: UIButton {
override var isHighlighted: Bool {
didSet {
if (isHighlighted) {
alpha = 0.5
}
else {
alpha = 1
}
}
}
}
utiliser https://github.com/swordray/UIButtonSetBackgroundColorForState
ajouter à Podfile en utilisant CocoaPods
pod "UIButtonSetBackgroundColorForState"
Swift
button.setBackgroundColor(.red, forState: .highlighted)
Objectif-C
[button setBackgroundColor:[UIColor redColor] forState:UIControlStateHighlighted];
si vous n'annulez pas il suffit de mettre deux actions touchdown touchUpInside
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)
}
}
il est possible de le régler par XIB. Dans XIB mettre mis en évidence la couleur de teinte comme le désir u tout en appuyant sur le bouton. Comme il n'y a pas d'approche programmatique juste pour cela jusqu'à présent. Donc c'est facile pour vous en le mettant en XIB .
, Il fonctionne très bien :) enjoy..