How to prevent bold images with UIImageRenderingModeAlwaysTemplate

后端 未结 4 1897
野性不改
野性不改 2020-12-31 19:30

My application has a toolbar with image buttons on them (subclass of UIButton); when the user switches on the \"Bold text\" accessibility option, not only the text becomes b

相关标签:
4条回答
  • 2020-12-31 19:33

    This is a swift 3 version of rufel Answer ,

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

    OR

    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;
    }
    }
    
    0 讨论(0)
  • 2020-12-31 19:40

    Thanks to Rufel's answer I was able to fix my issue and reduce the code of my class at the same 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
    
    0 讨论(0)
  • 2020-12-31 19:41

    Swift solution:

    Set Default rendering mode on image (in asset catalog or from the code).

    Transform the image color with this function:

    extension UIImage {
        public func transform(withNewColor color: UIColor) -> UIImage
        {
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
    
            let context = UIGraphicsGetCurrentContext()!
            context.translateBy(x: 0, y: size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.setBlendMode(.normal)
    
            let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            context.clip(to: rect, mask: cgImage!)
    
            color.setFill()
            context.fill(rect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return newImage
        }
    
    }
    

    Set transformed image to button desired state:

    let redImage = image.transform(withNewColor: UIColor.red)
    btn?.setImage(redImage, for: .selected)
    
    0 讨论(0)
  • 2020-12-31 19:56

    I recommend you to use a custom category to tint your image buttons. Here is a simple implementation that does just that:

    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
    

    To use it, just import "UIImage+TintImage.h", then do the following:

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

    button showcase

    0 讨论(0)
提交回复
热议问题