Background info: I have a UIImageView
. I have added an overlay colour on its image in the following way:
UIGraphicsBeginImageContext(initialImage.size);
[initialImage drawInRect:CGRectMake(0, 0, initialImage.size.width, initialImage.size.height) blendMode:kCGBlendModeNormal alpha:alphaValue];
UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, initialImage.size.width, initialImage.size.height)];
[overlayColor setFill];
[path fillWithBlendMode:kCGBlendModeMultiply alpha:1];
finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setImage:finalImage];
I still want to add this as an overlay colour but I want it to have a gradient. I have been trying to figure out a way to do this but haven't really been successful. I guess, the approach of adding an overlay colour with a gradient is wrong? I'm not sure about how to do this. I have tried to add a CGGradientLayer
as a sublayer
to the UIImageView
but it doesn't work.
I thought about adding a UIView
and setting it's backgroundColor
as the overlayColor
and then adding a CGGradientLayer
as sublayer
of the UIView
which is added as a subview
to the UIImageView
but, we are not supposed to add subviews
to UIImageViews
.
Can someone please help me with this? Maybe I should change my approach?
Pointing me in the right direction will be great as well!
I look forward to your responses and apologies if this post hasn't been entirely clear!
Thanks in advance for your help!
Edit: Code for the CGGradientLayer
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.frame;
UIColor *colorOne = [UIColor colorFromHex:self.feedColor withAlpha:(alphaValue * 0.7)];
UIColor *colorTwo = [UIColor colorFromHex:self.feedColor withAlpha:(alphaValue * 1.0)];
gradient.colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, (id)colorTwo.CGColor, nil];
[self.layer insertSublayer:gradient atIndex:0];
If you're looking for a more dynamic approach, then I would subclass CALayer
instead of UIImageView
. Therefore you'd want something like this:
@interface gradientImageLayer : CALayer
- (instancetype)initWithFrame:(CGRect)frame;
@end
@implementation gradientImageLayer
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super init]) {
self.opaque = YES; // Best for performance, but you if you want the layer to have transparency, then remove.
UIImage *i = [UIImage imageNamed:@"foo2.png"]; // Replace with your image
self.frame = frame;
self.contentsScale = [UIScreen mainScreen].nativeScale;
self.contents = (__bridge id _Nullable)(i.CGImage);
// Your code for the CAGradientLayer was indeed correct.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = frame;
// Add whatever colors you want here.
UIColor *colorOne = [UIColor colorWithRed:1 green:1 blue:0 alpha:0.1];
UIColor *colorTwo = [UIColor colorWithRed:0 green:1 blue:1 alpha:0.2];
gradient.colors = @[(id)colorOne.CGColor, (id)colorTwo.CGColor]; // Literals read far nicer than a clunky [NSArray arrayWith.... ]
[self addSublayer:gradient];
}
return self;
}
@end
The downside to this approach is you are unable to apply different blend modes. The only solutions I've seen to applying a blend mode on a CALayer
is through Core Graphics, but then you'd be better off with my original answer.