首页 文章

如何在iOS和WatchKit中更改图像tintColor

提问于
浏览
321

我有一个名为“theImageView”的UIImageView,UIImage为单色(透明背景),就像下面的左黑心一样 . 如何根据iOS 7导航栏图标中使用的色调方法在iOS 7或更高版本中以编程方式更改此图像的色调?

此方法是否也可以在WatchKit中用于Apple Watch应用程序?

enter image description here

18 回答

  • 27

    用于着色UIButton的图像

    let image1 = "ic_shopping_cart_empty"
        btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .normal)
            btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .selected)
            btn_Basket.imageView?.tintColor = UIColor(UIColor.Red)
    
  • 27

    这是我的UIImage扩展,您可以直接对图像使用changeTintColor函数 .

    extension UIImage {
    
        func changeTintColor(color: UIColor) -> UIImage {
            var newImage = self.withRenderingMode(.alwaysTemplate)
            UIGraphicsBeginImageContextWithOptions(self.size, false, newImage.scale)
            color.set()
            newImage.draw(in: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height))
            newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return newImage
        }
    
        func changeColor(color: UIColor) -> UIImage {
            let backgroundSize = self.size
            UIGraphicsBeginImageContext(backgroundSize)
            guard let context = UIGraphicsGetCurrentContext() else {
                return self
            }
            var backgroundRect = CGRect()
            backgroundRect.size = backgroundSize
            backgroundRect.origin.x = 0
            backgroundRect.origin.y = 0
    
            var red: CGFloat = 0
            var green: CGFloat = 0
            var blue: CGFloat = 0
            var alpha: CGFloat = 0
            color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
            context.setFillColor(red: red, green: green, blue: blue, alpha: alpha)
            context.translateBy(x: 0, y: backgroundSize.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.clip(to: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height),
                     mask: self.cgImage!)
            context.fill(backgroundRect)
    
            var imageRect = CGRect()
            imageRect.size = self.size
            imageRect.origin.x = (backgroundSize.width - self.size.width) / 2
            imageRect.origin.y = (backgroundSize.height - self.size.height) / 2
    
            context.setBlendMode(.multiply)
            context.draw(self.cgImage!, in: imageRect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage!
        }
    
    }
    

    像这样的用法示例

    let image = UIImage(named: "sample_image")
    imageView.image = image.changeTintColor(color: UIColor.red)
    

    您可以使用更改 changeColor 功能来更改图像颜色

  • 78

    斯威夫特4

    更改 UIImage SVG / PDF 的色调,适用于 image with unique color

    enter image description here

    enter image description here

    import Foundation
    
    // MARK: - UIImage extensions
    
    public extension UIImage {
    
        //
        /// Tint Image
        ///
        /// - Parameter fillColor: UIColor
        /// - Returns: Image with tint color
        func tint(with fillColor: UIColor) -> UIImage? {
            let image = withRenderingMode(.alwaysTemplate)
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            fillColor.set()
            image.draw(in: CGRect(origin: .zero, size: size))
    
            guard let imageColored = UIGraphicsGetImageFromCurrentImageContext() else {
                return nil
            }
    
            UIGraphicsEndImageContext()
            return imageColored
        }
    }
    

    更改 UIImageView 的色调,适用于 image with unique color

    enter image description here

    enter image description here

    let imageView = UIImageView(frame: CGRect(x: 50, y: 50, width: 50, height: 50))
    imageView.image = UIImage(named: "hello.png")!.withRenderingMode(.alwaysTemplate)
    imageView.tintColor = .yellow
    

    picture 更改 UIImage 的色调,使用:

    enter image description here

    enter image description here

    import Foundation
    
    // MARK: - Extensions UIImage
    
    public extension UIImage {
    
        /// Tint, Colorize image with given tint color
        /// This is similar to Photoshop's "Color" layer blend mode
        /// This is perfect for non-greyscale source images, and images that 
        /// have both highlights and shadows that should be preserved<br><br>
        /// white will stay white and black will stay black as the lightness of 
        /// the image is preserved
        ///
        /// - Parameter TintColor: Tint color
        /// - Returns:  Tinted image
        public func tintImage(with fillColor: UIColor) -> UIImage {
    
            return modifiedImage { context, rect in
                // draw black background - workaround to preserve color of partially transparent pixels
                context.setBlendMode(.normal)
                UIColor.black.setFill()
                context.fill(rect)
    
                // draw original image
                context.setBlendMode(.normal)
                context.draw(cgImage!, in: rect)
    
                // tint image (loosing alpha) - the luminosity of the original image is preserved
                context.setBlendMode(.color)
                fillColor.setFill()
                context.fill(rect)
    
                // mask by alpha values of original image
                context.setBlendMode(.destinationIn)
                context.draw(context.makeImage()!, in: rect)
            }
        }
    
        /// Modified Image Context, apply modification on image
        ///
        /// - Parameter draw: (CGContext, CGRect) -> ())
        /// - Returns:        UIImage
        fileprivate func modifiedImage(_ draw: (CGContext, CGRect) -> ()) -> UIImage {
    
            // using scale correctly preserves retina images
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            let context: CGContext! = UIGraphicsGetCurrentContext()
            assert(context != nil)
    
            // correctly rotate image
            context.translateBy(x: 0, y: size.height)
            context.scaleBy(x: 1.0, y: -1.0)
    
            let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
    
            draw(context, rect)
    
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return image!
        }
    }
    
  • 3

    试试这个

    http://robots.thoughtbot.com/designing-for-ios-blending-modes

    要么

    - (void)viewDidLoad
    {
    [super viewDidLoad];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 300, 50)];
    label.numberOfLines = 0;
    label.font = [UIFont systemFontOfSize:13];
    label.text = @"These checkmarks use the same gray checkmark image with a tintColor applied to the image view";
    [self.view addSubview:label];
    
    [self _createImageViewAtY:100 color:[UIColor purpleColor]];
    }
    
    - (void)_createImageViewAtY:(int)y color:(UIColor *)color {
    UIImage *image = [[UIImage imageNamed:@"gray checkmark.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    CGRect frame = imageView.frame;
    frame.origin.x = 100;
    frame.origin.y = y;
    imageView.frame = frame;
    
    if (color)
        imageView.tintColor = color;
    
    [self.view addSubview:imageView];
    }
    
  • 0

    profileImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
    profileImageView.tintColor = UIColor.green

    要么

    首先选择图像资源中的特定图像,然后选择红色为模板而不是默认值,然后选择该写入行 . profileImageView.tintColor = UIColor.green

  • 1

    Swift 3 扩展答案的版本来自 fuzz

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

    如果您有图像来替换清除按钮,则可以在Swift 3中使用它

    func addTextfieldRightView(){
    
        let rightViewWidth:CGFloat = 30
    
        let viewMax = self.searchTxt.frame.height
        let buttonMax = self.searchTxt.frame.height - 16
    
        let buttonView = UIView(frame: CGRect(
            x: self.searchTxt.frame.width - rightViewWidth,
            y: 0,
            width: viewMax,
            height: viewMax))
    
        let myButton = UIButton(frame: CGRect(
            x: (viewMax - buttonMax) / 2,
            y: (viewMax - buttonMax) / 2,
            width: buttonMax,
            height: buttonMax))
    
        myButton.setImage(UIImage(named: "BlueClear")!, for: .normal)
    
        buttonView.addSubview(myButton)
    
        let clearPressed = UITapGestureRecognizer(target: self, action: #selector(SearchVC.clearPressed(sender:)))
        buttonView.isUserInteractionEnabled = true
        buttonView.addGestureRecognizer(clearPressed)
    
        myButton.addTarget(self, action: #selector(SearchVC.clearPressed(sender:)), for: .touchUpInside)
    
        self.searchTxt.rightView = buttonView
        self.searchTxt.rightViewMode = .whileEditing
    }
    
  • 15

    现在我使用这个基于Duncan Babbage响应的方法:

    + (UIImageView *) tintImageView: (UIImageView *)imageView withColor: (UIColor*) color{
        imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        [imageView setTintColor:color];
        return imageView;
    }
    
  • 116

    这是一个应该做的技巧

    @interface UIImage(Overlay)
    @end
    
    @implementation UIImage(Overlay)
    
    - (UIImage *)imageWithColor:(UIColor *)color1
    {
            UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
            CGContextRef context = UIGraphicsGetCurrentContext();
            CGContextTranslateCTM(context, 0, self.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextSetBlendMode(context, kCGBlendModeNormal);
            CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
            CGContextClipToMask(context, rect, self.CGImage);
            [color1 setFill];
            CGContextFillRect(context, rect);
            UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            return newImage;
    }
    @end
    

    所以你会这样做:

    theImageView.image = [theImageView.image imageWithColor:[UIColor redColor]];
    
  • 84

    iOS

    从InterfaceBuilder,set templateImage param in keyPath执行此操作的解决方案,并选择您从IB着色

    extension UIImageView {
    
    // make template image with tint color
    var templateImage: Bool {
        set {
            if newValue, let image = self.image {
                let newImage = image.withRenderingMode(.alwaysTemplate)
                self.image = newImage
            }
        } get {
            return false
        }
    }
    

    }

  • 0

    我必须使用 extension 在Swift中执行此操作 .

    我以为我会分享我是怎么做到的:

    extension UIImage {
        func imageWithColor(color1: UIColor) -> UIImage {
            UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
            color1.setFill()
    
            let context = UIGraphicsGetCurrentContext() as CGContextRef
            CGContextTranslateCTM(context, 0, self.size.height)
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextSetBlendMode(context, CGBlendMode.Normal)
    
            let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
            CGContextClipToMask(context, rect, self.CGImage)
            CGContextFillRect(context, rect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
            UIGraphicsEndImageContext()
    
            return newImage
        }
    }
    

    用法:

    theImageView.image = theImageView.image.imageWithColor(UIColor.redColor())

    Swift 4

    extension UIImage {
        func imageWithColor(color1: UIColor) -> UIImage {
            UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
            color1.setFill()
    
            let context = UIGraphicsGetCurrentContext()
            context?.translateBy(x: 0, y: self.size.height)
            context?.scaleBy(x: 1.0, y: -1.0)
            context?.setBlendMode(CGBlendMode.normal)
    
            let rect = CGRect(origin: .zero, size: CGSize(width: self.size.width, height: self.size.height))
            context?.clip(to: rect, mask: self.cgImage!)
            context?.fill(rect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return newImage!
        }
    }
    

    用法:

    theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)

  • 0

    Take benefit of Extension in Swift :-

    extension UIImageView {
        func changeImageColor( color:UIColor) -> UIImage
        {
            image = image!.withRenderingMode(.alwaysTemplate)
            tintColor = color
            return image!
        }
    }
    
       //Change color of logo 
       logoImage.image =  logoImage.changeImageColor(color: .red)
    

    enter image description here

  • 0

    可以从代码和Interface Builder中使用的子类:

    @implementation TintedImageView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    -(void)setup {
        self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    }
    
    @end
    
  • 3

    在故事板和图像资产 . 你也可以改变这两个:

    将渲染模式更新为模板图像

    Update the Render Mode to Template Image in Image Assets

    更新视图中的色调颜色 .

    Update the tint Color in Views in Views

  • 1

    随着Swift

    let commentImageView = UIImageView(frame: CGRectMake(100, 100, 100, 100))
    commentImageView.image = UIImage(named: "myimage.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
    commentImageView.tintColor = UIColor.blackColor()
    addSubview(commentImageView)
    
  • 0

    iOS
    对于iOS应用程序,在Swift 3或4中:

    theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
    theImageView.tintColor = UIColor.red
    

    斯威夫特2:

    theImageView.image = theImageView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
    theImageView.tintColor = UIColor.redColor()
    

    同时,现代的Objective-C解决方案是:

    theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    [theImageView setTintColor:[UIColor redColor]];
    

    Watchkit
    在WatchKit for Apple Watch应用程序中,您可以设置tint color for a template image .

    • 您必须将图像添加到WatchKit应用程序中的资产目录,并将图像集设置为在属性检查器中呈现为模板图像 . 与iPhone应用程序不同,您目前无法在WatchKit Extension中的代码中设置模板渲染 .

    • 设置要在应用程序的界面构建器中的WKInterfaceImage中使用的图像

    • 在WKInterfaceController中为名为'theImage'的WKInterfaceImage创建一个IBOutlet ...

    然后在Swift 3或4中设置色调颜色:

    theImage.setTintColor(UIColor.red)
    

    斯威夫特2:

    theImage.setTintColor(UIColor.redColor())
    

    然后在Objective-C中设置色调颜色:

    [self.theImage setTintColor:[UIColor redColor]];
    

    如果您使用模板图像并且不应用色调颜色,则将应用WatchKit应用程序的全局色调 . 如果尚未设置全局色调,则 theImage 在用作模板图像时将默认为浅蓝色 .

  • -1

    如果有人关心没有 UIImageView 的解决方案:

    // (Swift 3)
    extension UIImage {
        func tint(with color: UIColor) -> UIImage {
            var image = withRenderingMode(.alwaysTemplate)
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            color.set()
    
            image.draw(in: CGRect(origin: .zero, size: size))
            image = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return image
        }
    }
    
  • 604

    为了迅速3目的

    theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate) theImageView.tintColor = UIColor.red

相关问题