titlelabel guidelines color buttons ios objective-c xcode uibutton

guidelines - menu ios



¿Cómo cambiar el color de fondo de un UIButton mientras está resaltado? (27)

En algún punto de mi aplicación tengo un UIButton resaltado (por ejemplo, cuando un usuario tiene su dedo en el botón) y necesito cambiar el color de fondo mientras el botón está resaltado (por lo que mientras el dedo del usuario todavía está en el botón ).

Intenté lo siguiente:

_button.backgroundColor = [UIColor redColor];

Pero no está funcionando. El color sigue siendo el mismo. Intenté el mismo código cuando el botón no está resaltado y funciona bien. También intenté llamar a -setNeedsDisplay después de cambiar el color, no tuvo ningún efecto.

¿Cómo forzar el botón para cambiar el color de fondo?


ACTUALIZAR:

Utilice la biblioteca UIButtonBackgroundColor Swift.

ANTIGUO:

Use los ayudantes a continuación para crear una imagen de 1 px x 1 px con un color de relleno en escala de grises:

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

o un color de relleno RGB:

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

Luego, usa esa image para establecer la imagen de fondo del botón:

[button setBackgroundImage:image forState:UIControlStateNormal];

Ayudantes

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

Nota: ACU es el prefijo de clase de mi biblioteca estática de Cocoa Touch llamada Acani Utilities, donde AC es para Acani, y U es para Utilities.


Anular la variable resaltada. Agregar @IBInspectable te hace editar el fondo de @IBInspectable resaltado en el guión gráfico, que también es ingenioso.

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


Aquí está el código en Swift para seleccionar el estado del botón:

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

Ejemplo:

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


Aquí hay un enfoque en Swift, utilizando una extensión UIButton para agregar un IBInspectable, llamado highlightBackgroundColor. Similar a la subclasificación, sin requerir una subclase.

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

Espero que esto ayude.


Déjalo y ya estás listo para ir:
* proerty se puede configurar en IB, y si no se establece un fondo resaltado, el fondo no cambiará cuando se presione

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


Debajo de la extensión UIIImage se generará un objeto de imagen con el parámetro de color especificado.

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

Se puede aplicar un ejemplo de uso de un botón para el objeto de botón como:

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)


En Swift puede anular el acceso a la propiedad resaltada (o seleccionada) en lugar de anular el método setHighlighted

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


Es posible configurarlo a través de XIB. En xib, establezca el color de tinte resaltado como desee mientras presiona el botón. Como no hay un enfoque programáticamente correcto para esto hasta ahora. Así que es fácil para ti configurándolo en XIB.

Funcionará bien :) disfrutar ..


Extensión de UIButton con sintaxis 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) }}

Utilízalo como:

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

Respuesta original: https://.com/a/30604658/3659227


He abierto una subclase STAButton , STAButton , para completar este agujero de funcionalidad enorme. Disponible bajo la licencia MIT. Funciona para iOS 7+ (no he probado con versiones anteriores de iOS).


Intenta esto si tienes una imagen:

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

o ve si showsTouchWhenHighlighted es suficiente para ti.


Mi mejor solución para Swift 3+ sin subclases.

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

Con esta extensión es fácil administrar los colores para diferentes estados y desvanecerá su color normal automáticamente en caso de que no se proporcione el color resaltado.

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


No estoy seguro de si este tipo de solución resuelve lo que está buscando, o si se ajusta al panorama de desarrollo general, pero lo primero que intentaría sería cambiar el color de fondo del botón en el evento touchDown.

Opción 1:

Necesitaría dos eventos para capturar, UIControlEventTouchDown sería para cuando el usuario presione el botón. UIControlEventTouchUpInside y UIControlEventTouchUpOutside serán para cuando suelten el botón y regresen al estado 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];

Opcion 2:

Devuelve una imagen hecha del color de resaltado que deseas. Esto también podría ser una categoría.

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

y luego cambiar el estado resaltado del botón:

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


No hay necesidad de anular highlighted como propiedad computada. Puedes usar la propiedad observadora para activar el cambio de color de fondo:

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


Para resolver este problema, creé una categoría para manejar los estados de UIButtons backgroundColor con UIButtons :
ButtonBackgroundColor-iOS

Puede instalar la categoría como un pod .

Fácil de usar con Objective-C

@property (nonatomic, strong) UIButton *myButton; ... [self.myButton bbc_backgroundColorNormal:[UIColor redColor] backgroundColorSelected:[UIColor blueColor]];

Aún más fácil de usar con Swift :

import ButtonBackgroundColor ... let myButton:UIButton = UIButton(type:.Custom) myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())

Te recomiendo que importes el pod con:

platform :ios, ''8.0'' use_frameworks! pod ''ButtonBackgroundColor'', ''~> 1.0''

Usando use_frameworks! en su Podfile hace que sea más fácil usar sus pods con Swift y object-C.

IMPORTANTE

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


Prueba tintColor :

_button.tintColor = [UIColor redColor];


Prueba esto !!!!

Para TouchedDown Event set Un color y para TouchUpInside establece el otro.

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


Puede anular el método setHighlighted .

C objetivo

- (void)setHighlighted:(BOOL)highlighted { [super setHighlighted:highlighted]; if (highlighted) { self.backgroundColor = UIColorFromRGB(0x387038); } else { self.backgroundColor = UIColorFromRGB(0x5bb75b); } }

Swift 3.0 y Swift 4.1

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



Puedes subclasificar el UIButton y hacer un buen estado para el estado.

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

Notas (Este es un ejemplo, sé que hay problemas y aquí hay algunos)

He usado un NSMutableDictionay para almacenar el UIColor para cada estado, tengo que hacer una conversión de texto desagradable para la clave, ya que UIControlState no es un buen Int. Directo. Si es donde podría iniciar una matriz con tantos objetos y usar el estado como un índice.

Debido a esto, muchos tienen dificultades con, por ejemplo, un botón seleccionado y deshabilitado, se necesita algo más de lógica.

Otro problema es que si intenta configurar varios colores al mismo tiempo, no lo he intentado con un botón, pero si puede hacerlo, puede que no funcione.

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

He asumido que esto es StoryBoard, no hay init, initWithFrame, así que agréguelos si los necesita.


Subclase el UIButton y agregue propiedades inspeccionables para un uso conveniente (escrito en 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 } } } }


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


Una extensión genérica práctica en 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) } }


Una solución más compacta (basada en la respuesta de @ 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() } }

Si no quieres anular, esta es una versión actualizada de la respuesta de @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) } }



si no anula, simplemente establece dos acciones touchDown touchUpInside


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