3

I am working on an app where elements need to be customizable in different colors. Up to this point I have been taking advantage of tintColor and imageWithRenderingMode to change image colors. I am currently in a situation where I need to add a background tile image using UIColor(patternImage:) and backgroundColor. Is there a way to apply a kind of tint to the background tile image so I can change the background image color at runtime?

J_P
  • 51
  • 1
  • 6
  • The approach listed [here](http://stackoverflow.com/a/28449269/759635) worked for me. – J_P Aug 13 '15 at 18:36

4 Answers4

2

J_P, thanks for your answer! It's really helpful. I just want to post an updated version for Swift 5

extension UIColor {
    convenience init(patternImage: UIImage, tintColor: UIColor) {
        var image = patternImage.withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(patternImage.size,
                                               false,
                                               patternImage.scale)
        tintColor.set()   
        image.draw(in: CGRect(x: 0, y: 0,
                              width: patternImage.size.width,
                              height: patternImage.size.height))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        self.init(patternImage: image)
    }
}
LordPingvin
  • 163
  • 2
  • 7
1

You can apply TintColor to UIImage and Use that UIImage as a background color for tiling.

For Applying tintColor to UIImage:

- (UIImage *) addOverlaytoImage:(UIImage *)mySourceImage
{
    UIImage * image = mySourceImage;
    UIColor * color = [UIColor yellowColor];
    UIGraphicsBeginImageContext(image.size);
    [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height) blendMode:kCGBlendModeNormal alpha:1];
    UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    [color setFill];
    [path fillWithBlendMode:kCGBlendModeMultiply alpha:1]; //look up blending modes for your needs
    UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

And then add this image to Background Color parameter:

yourView.backgroundColor = [UIColor colorWithPatternImage:[self addOverlaytoImage:myImage]]; 

Please refer following link: Designing for iOS: Blending Modes

halfer
  • 19,824
  • 17
  • 99
  • 186
0

With the link that I found here this is what I got it to work

// originalImage and originalColor are defined
var image = originalImage.imageWithRenderingMode(.AlwaysTemplate)
UIGraphicsBeginImageContextWithOptions(
    originalImage.size,
    false,
    originalImage.scale)
originalColor.set()
image.drawInRect(CGRectMake(
    0,
    0,
    originalImage.size.width,
    originalImage.size.height))
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIColor(patternImage: image)
Community
  • 1
  • 1
J_P
  • 51
  • 1
  • 6
0

Another version with dynamic tintColor that supports light/dark mode:

extension UIColor {
    convenience init(patternImage: UIImage, tintColor: UIColor) {
        self.init(dynamicProvider: { traitCollection in
            var staticColor: UIColor = .clear

            traitCollection.performAsCurrent {
                var image = patternImage.withRenderingMode(.alwaysTemplate)
                UIGraphicsBeginImageContextWithOptions(patternImage.size,
                                                       false,
                                                       patternImage.scale)
                tintColor.set()
                image.draw(in: CGRect(x: 0, y: 0,
                                      width: patternImage.size.width,
                                      height: patternImage.size.height))
                image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
                UIGraphicsEndImageContext()

                staticColor = UIColor(patternImage: image)
            }

            return staticColor
        })
    }
}
kaverin
  • 19
  • 2