Se você tiver um UIButton que usa a mesma imagem para UIControlStateSelected e UIControlStateHighlighted, provavelmente notou que as imagens tremem quando o botão é tocado rapidamente. O UIKit trata o estado do botão como um sinalizador de bit enumerado, portanto, durante um evento de toque rápido, o botão existe em um estado em que é selecionado e destacado.
Para corrigir a cintilação, o UIButton precisa ter a imagem definida para o estado UIControlStateSelected | UIControlStateHighlighted.
UIImage *sl = [self imageForState:UIControlStateSelected];
[aButton setImage:sl forState:(UIControlStateSelected | UIControlStateHighlighted)];
Para aplicar esta correção a todos os UIButtons carregados de arquivos NIB, crie uma nova categoria UIButton contendo os seguintes métodos.
void UIButtonAwakeFromNibSwizzle() {
Class c = [UIButton class];
SEL orig = @selector(awakeFromNib);
SEL new = @selector(fixedAwakeFromNib);
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
}
- (void)fixedAwakeFromNib {
// swizzled functions get exchanged, so calling fixedAwakeFromNib calls the original function
[self fixedAwakeFromNib];
UIImage *hl = [self imageForState:UIControlStateHighlighted];
UIImage *sl = [self imageForState:UIControlStateSelected];
if (hl == sl) {
[self setImage:hl forState:(UIControlStateSelected | UIControlStateHighlighted)];
}
}
Agora, se você chamar UIButtonAwakeFromNibSwizzle () em didFinishLaunchingWithOptions do Delegado do Aplicativo, fixedAwakeFromNib será chamado sempre que um UIButton chamar awakeFromNib.