Comment éviter les images en gras avec UIImageRenderingModeAlwaysTemplate

Mon application a une barre d'outils avec des buttons d'image sur eux (sous-class de UIButton); lorsque l'user active l'option d'accessibilité "Gras", non seulement le text devient gras mais les images suivent.

C'est la barre d'outils en mode normal:

Barre d'outils en mode normal

Lorsque le "text en gras" est activé:

Barre d'outils en mode gras

Il semble provenir de ma sous-class UIButton, qui est incluse ci-dessous. J'utilise cette class pour appliquer une couleur de teinte d'image lorsque le button est cliqué, désactivé, etc. et évite d'avoir à inclure plusieurs états de chaque button. Pour cela j'utilise le UIImageRenderingModeAlwaysTemplate qui présente ce comportement observé.

J'ai essayé de décocher l'option "Accessibilité" dans le constructor de l'interface, mais cela n'a eu aucun effet. Y'a t'il un moyen d'arranger cela?

 #import "AppButton.h" @implementation AppButton - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self initialize]; } return self; } - (void)initialize { self.adjustsImageWhenHighlighted = NO; [self setImage:[[self imageForState:UIControlStateNormal] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; } - (void)updateButtonView { if (!self.enabled) { self.imageView.tintColor = [UIColor colorWithRGBValue:RGBValueC9]; } else if (self.highlighted) { self.imageView.tintColor = self.highlightTintColor; } else { self.imageView.tintColor = self.tintColor; } } - (void)setHighlighted:(BOOL)highlighted { [super setHighlighted:highlighted]; [self updateButtonView]; } - (void)setEnabled:(BOOL)enabled { [super setEnabled:enabled]; [self updateButtonView]; } - (void)setTintColor:(UIColor *)tintColor { [super setTintColor:tintColor]; [self updateButtonView]; } @end 

    Je vous recommand d'utiliser une catégorie personnalisée pour teinter vos buttons d'image. Voici une implémentation simple qui ne fait que cela:

    UIImage + TintImage.h

     @interface UIImage (TintImage) - (UIImage *)imageTintedWithColor:(UIColor *)tintColor; @end 

    UIImage + TintImage.m

     #import "UIImage+TintImage.h" @implementation UIImage (TintImage) - (UIImage *)imageTintedWithColor:(UIColor *)tintColor { if (tintColor == nil) { tintColor = [UIColor whiteColor]; } CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f); // Tint image [tintColor set]; UIRectFill(rect); [self drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tintedImage; } @end 

    Pour l'utiliser, il suffit d'importer "UIImage+TintImage.h" , puis procédez comme suit:

     UIImage *originalImage = [UIImage imageNamed:@"icn-menu"]; UIImage *tintedImage = [originalImage imageTintedWithColor:[UIColor blueColor]]; UIButton *homeButton = [UIButton buttonWithType:UIButtonTypeCustom]; [homeButton setImage:originalImage forState:UIControlStateNormal]; [homeButton setImage:tintedImage forState:UIControlStateHighlighted]; 

    bouton vitrine

    Grâce à la réponse de Rufel, j'ai pu résoudre mon problème et réduire le code de ma class en même time:

     #import "AppButton.h" @interface AppButton () @property (readonly) UIImage *normalImage; @end @implementation AppButton @synthesize highlightTintColor = _highlightTintColor; - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self initialize]; } return self; } - (UIImage *)normalImage { return [self imageForState:UIControlStateNormal]; } - (void)initialize { self.adjustsImageWhenHighlighted = NO; // set disabled image [self setImage:[self image:self.normalImage tintedWithColor:[UIColor colorWithRGBValue:RGBValueC9]] forState:UIControlStateDisabled]; } - (void)setHighlightTintColor:(UIColor *)highlightTintColor { _highlightTintColor = highlightTintColor; // update highlighted image if (highlightTintColor) { [self setImage:[self image:self.normalImage tintedWithColor:highlightTintColor] forState:UIControlStateHighlighted]; } } - (UIImage *)image:(UIImage *)image tintedWithColor:(UIColor *)tintColor { CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0f); // Tint image [tintColor set]; UIRectFill(rect); [image drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tintedImage; } @end 

    Ceci est une version rapide de 3 rufel Réponse,

     extension UIImageView { fileprivate func tintImage(color: UIColor){ guard let _image = image else { return } let rect = CGRect(x: 0.0, y: 0.0, width: _image.size.width , height: _image.size.height ) UIGraphicsBeginImageContextWithOptions(_image.size , false, _image.scale) color.set() UIRectFill(rect) _image.draw(in: rect, blendMode: CGBlendMode.destinationIn, alpha: 1.0) image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } } 

    OU

     extension UIImage { static func imageTinted(image: UIImage?, color: UIColor) -> UIImage? { let rect = CGRect(x: 0.0, y: 0.0, width: image?.size.width ?? 0.0, height: image?.size.height ?? 0.0) UIGraphicsBeginImageContextWithOptions(image?.size ?? CGSize.zero, false, image?.scale ?? 2.0) color.set() UIRectFill(rect) image?.draw(in: rect, blendMode: CGBlendMode.destinationIn, alpha: 1.0) let tinted = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); return tinted; } }