Skip to content

Instantly share code, notes, and snippets.

@longlongjump
Last active April 6, 2020 14:56
Show Gist options
  • Save longlongjump/6951172 to your computer and use it in GitHub Desktop.
Save longlongjump/6951172 to your computer and use it in GitHub Desktop.
"dynamic" blur using layer mask
#import <UIKit/UIKit.h>
@interface BlurredView : UIView
-(void)update;
@end
//
// BlurredView.m
//
// Created by Hellier on 04.10.13.
// Copyright (c) 2013 void. All rights reserved.
//
#import "BlurredView.h"
@interface UIImage(Blur)
-(UIImage*)blurWithRadius:(float)radius;
@end
@implementation UIImage(Blur)
-(UIImage*)blurWithRadius:(float)radius
{
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *imageToBlur = [CIImage imageWithCGImage:self.CGImage];
CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
[gaussianBlurFilter setValue:imageToBlur forKey: @"inputImage"];
[gaussianBlurFilter setValue:@(radius) forKey: @"inputRadius"];
CIImage *resultImage = [gaussianBlurFilter valueForKey: @"outputImage"];
CGImageRef cgImage = [context createCGImage:resultImage fromRect:[imageToBlur extent]];
return [[UIImage alloc] initWithCGImage:cgImage];
}
@end
@interface BlurredView()
@property (strong,nonatomic) UIImageView *imageView;
@property (strong,nonatomic) UIView *maskView;
@end
@implementation BlurredView
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
self.maskView = [[UIView alloc] init];
self.maskView.backgroundColor = [UIColor blackColor];
self.imageView = [[UIImageView alloc] init];
self.imageView.clipsToBounds = YES;
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
self.imageView.layer.mask = self.maskView.layer;
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
self.clipsToBounds = YES;
}
-(UIImage*)renderToImage:(UIView*)view
{
float scale = [UIScreen mainScreen].scale;
CGSize size = view.frame.size;
size.width*=scale; size.height*=scale;
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, 0);
CALayer *layer = view.layer;
self.layer.hidden = YES;
[layer renderInContext:context];
self.layer.hidden = NO;
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
-(void)update
{
self.imageView.image = [[self renderToImage:self.superview] blurWithRadius:6];
}
-(void)setBounds:(CGRect)bounds
{
self.maskView.bounds = bounds;
[super setBounds:bounds];
}
-(void)setCenter:(CGPoint)center
{
self.maskView.center = center;
[super setCenter:center];
}
-(void)didMoveToSuperview
{
if (self.superview)
{
self.imageView.frame = self.superview.bounds;
[self.superview insertSubview:self.imageView belowSubview:self];
self.maskView.frame = self.frame;
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self update];
});
} else
{
[self.imageView removeFromSuperview];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment