How to mask a UIView
Solution 1
// Create your mask layer
CALayer* maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0,0,yourMaskWidth ,yourMaskHeight);
maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"yourMaskImage.png"] CGImage];
// Apply the mask to your uiview layer
yourUIView.layer.mask = maskLayer;
Remember to import QuartzCore and add the framework
#import <QuartzCore/QuartzCore.h>
It is very easy but I didn't find the answer anywhere!
Solution 2
iOS 8 introduces the maskView
property which allows you to use an alternate view to provide the mask image. In Swift:
if let maskImage = UIImage(named: "MaskImage") {
myView.maskView = UIImageView(image: maskImage)
}
Note that you need to supply an image which actually has transparency; an image with white parts (for opaque) and black parts (for transparent) won't work.
Solution 3
You might be able to use CGContextClipToMask:
-(void) drawRect:(CGRect)dirty {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState( context );
CGContextClipToMask( context , [self bounds] , [self maskImage] );
[super drawRect:dirty]; // or draw your color manually
CGContextRestoreGState( context );
}
Solution 4
I have create a category with the code above :
UIView+ImageMask.h :
#import <UIKit/UIKit.h>
@interface UIView (ImageMask)
- (void) maskWithImage:(UIImage*) mask;
- (void) maskWithImage:(UIImage*)mask size:(CGSize)maskSize;
- (void) removeMask;
@end
UIView+ImageMask.m :
#import <QuartzCore/QuartzCore.h>
#import "UIView+ImageMask.h"
@implementation UIView (ImageMask)
- (void) maskWithImage:(UIImage*) mask {
[self maskWithImage:mask size:mask.size];
}
- (void) maskWithImage:(UIImage*)mask size:(CGSize)maskSize {
CALayer* maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0, 0, maskSize.size.width, maskSize.size.height);
maskLayer.contents = (__bridge id)[mask CGImage];
// Apply the mask to your uiview layer
self.layer.mask = maskLayer;
}
- (void) removeMask {
self.layer.mask = nil;
}
@end
Solution 5
Thanks drawnonward,
ended up with this function:
- (UIImage*) maskImage:(UIView *)image withMask:(UIImage *)maskImage {
UIGraphicsBeginImageContext(image.bounds.size);
[image.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([viewImage CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
Related videos on Youtube
Thomas Joos
Mobile User Experience Designer with a strong development background in Flash Mobile and iPhone
Updated on July 09, 2022Comments
-
Thomas Joos almost 2 years
I'm working on an app where I draw a UIView via code and I fill it with a UIColor. Next thing I want to load a mask.png file (no transparency, just black and white) and mask the UIView to change its visual appearance.
Any idea how to do this?
-
zakdances about 11 yearsAny answer that uses Core Animation instead of Core Graphics should be preferred. CA's API is much easier to understand and use.
-
Vassily over 10 yearsWhat kind of image do you have in input ? black& white or translucent and white or translucent and black ?
-
mt81 over 10 yearsI used a black image with alpha. But I don't think this will make a difference. If you try it, let me know :).
-
Arsynth over 10 yearsI tried. Actually have a difference. Only alpha component will make effect
-
Vassily over 10 yearsyes, image needs to be PNG with alpha component. only the alpha will be masked, the rest can be white or black it doesn't matter
-
Yaroslav about 8 yearsAny idea why this might crash with EXC_BAD_ACCESS? (-[UIImageView _maskView]: message sent to deallocated instance)