Cómo evitar que UIButton destelle al actualizar el título
ios7 (8)
¡El comportamiento predeterminado de "setTitle" es definitivamente odioso!
Mi solución es:
[UIView setAnimationsEnabled:NO];
[_button layoutIfNeeded];
[_button setTitle:[NSString stringWithFormat:@"what" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
Además, en el guión gráfico, bajo la propiedad del botón, desmarcaré:
- Invierte en lo destacado
- Imagen de ajuste resaltada
Y mira:
- Imagen de ajuste desactivado
Probado y trabajando en iOS 8 también.
Actualización - Swift
Le sugiero que cree su botón personalizado y anule el método setTitle .
class UnflashingButton: UIButton {
override func setTitle(title: String?, forState state: UIControlState) {
UIView.setAnimationsEnabled(false)
self.layoutIfNeeded()
super.setTitle(title, forState: state)
UIView.setAnimationsEnabled(true)
}
}
Cuando llamo a setTitle en un UIButton, el botón parpadea en iOS 7. Intenté configurar myButton.highlighted = NO, pero eso no impidió que el botón parpadeara.
[myButton setTitle:[[NSUserDefaults standardUserDefaults] stringForKey:@"elapsedLabelKey"] forState:UIControlStateNormal];
myButton.highlighted = NO;
Aquí es cómo configuré el temporizador que actualizó los títulos:
- (void)actionTimer {
if (myTimer == nil) {
myTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(showActivity)
userInfo: nil
repeats: YES];
}
}
Aquí está el método que realmente actualiza los títulos:
- (void)showActivity {
NSString *sym = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
if (pauseInterval == nil) {
// Update clock
seconds = [[NSDate date] timeIntervalSinceDate:startInterval] - breakTime;
// Update total earned
secRate = rate.value / 60 / 60;
total = secRate * seconds;
[totalLabel setTitle:[NSString stringWithFormat:@"%@%.4f",sym,total] forState:UIControlStateNormal];
days = seconds / (60 * 60 * 24);
seconds -= days * (60 * 60 * 24);
int hours = seconds / (60 * 60);
fhours = (float)seconds / (60.0 * 60.0);
seconds -= hours * (60 * 60);
int minutes = seconds / 60;
seconds -= minutes * 60;
// Update the timer clock
[elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
}
}
* Tenga en cuenta *
cuando " buttonType " de _button es "UIButtonTypeSystem" , el siguiente código no es válido :
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
cuando " buttonType " de _button es "UIButtonTypeCustom" , el código anterior es válido .
Consulte las respuestas de Cómo detener la animación UIButton no deseada en el cambio de título? :
[UIView setAnimationsEnabled:NO];
[elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
El parpadeo no es causado por el temporizador per se. El método UIButton setTitle: forState causa el parpadeo. Un trabajo simple es usar un UIButton sin título y superponer un UILabel. Cuando cambie el texto de UILabel, no parpadeará.
Establezca el tipo de botón en UIButtonTypeCustom y dejará de parpadear
Simplemente puede hacer otra función para UIButton para un fácil uso futuro.
extension UIButton {
func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
UIView.performWithoutAnimation {
self.setTitle(title, for: controlState)
self.layoutIfNeeded()
}
}
}
¡Eso es!
Y simplemente configure el título como lo haría antes, pero reemplace setTitle
con setTitleWithoutAnimation
Soy nuevo en codificación y , por lo que no tengo la reputación suficiente para comentar directamente para ampliar excelente respuesta. Así que tengo que escribir mi propia respuesta nueva, y es esta:
extension UIButton {
func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
UIView.performWithoutAnimation {
self.setTitle(title, for: controlState)
self.layoutIfNeeded()
}
}
}
Funciona muy bien, EXCEPTO:
Si todas mis llamadas más tarde en el código para "setTitleWithoutAnimation" no especifican un remitente, entonces obtengo estos mensajes extraños relacionados con CoreMedia o CoreData, por ejemplo, "Falló la herencia de los permisos de CoreMedia desde 2526: (null)"
Esto es probablemente bastante básico para la codificación y el iOS, pero para mí como un nuevo codificador, me envió a un camino de conejo por un tiempo, como en: Today Extension Falló la herencia de los permisos de CoreMedia , donde la gente tenía respuestas interesantes pero eso NO llegar a la raíz de mi problema
Así que finalmente encontré que tenía que pasar y dar mis parámetros de funciones sin parámetros, es decir, tenía que especificar un remitente. Ese remitente podría ser UIButton, Any o AnyObject. Todos funcionaron, pero finalmente parece haber un conflicto entre agregar una extensión de botón con "self" y no decir más tarde específicamente que un botón lo está usando.
Nuevamente, probablemente básico, pero nuevo para mí, así que pensé que valdría la pena compartirlo.
Un mejor enfoque que [UIView setAnimationsEnabled:NO]
que puede afectar a otras animaciones es solo desactivar la animación del título específico.
C objetivo:
[UIView performWithoutAnimation:^{
[myButton setTitle:text forState:UIControlStateNormal];
[myButton layoutIfNeeded];
}];
Swift 3:
UIView.performWithoutAnimation {
myButton.setTitle(text, for: .normal)
myButton.layoutIfNeeded()
}