1

I am trying to blur the text of UILabel without image blurring methods. I found many solutions but maximum are there for images. I tried shadow functionality of layer but that is not helpful.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
Ravi Gautam
  • 960
  • 2
  • 9
  • 20
  • Check this answer. http://stackoverflow.com/questions/25390446/how-to-replicate-the-blurred-text-in-notification-center-ios-8 – Utsav Parikh May 18 '15 at 12:32
  • Thanks Utasav, But I don't want to use this kind of stuff because that can be heavy table cell. – Ravi Gautam May 18 '15 at 13:27
  • Position a blur image over the label. – Hot Licks May 18 '15 at 13:28
  • use this code to blur UILabel https://github.com/MuscleRumble/THLabel – amit gupta May 18 '15 at 12:25
  • @RaviGautam - In iOS 8 you can use `UIBlurEffect` and `UIVisualEffectView` to efficiently blur label. But that doesn't let you control the degree of blurring (and `UIBlurEffect` is pretty extreme). If you want more control over blurring, then you're stuck doing some image-based blurring like Core Image (as suggested by Lefteris (which is pretty computationally intensive) or using `iOS_UIImageEffects` from WWDC 2013. See http://stackoverflow.com/questions/19432773/creating-a-blur-effect-in-ios7/19433086#19433086 – Rob May 19 '15 at 21:14
  • @RaviGautam check my answer with a custom UILabel that can blur through GaussianBlur: https://stackoverflow.com/a/62224908/3564632 – denis_lor Jun 05 '20 at 22:22
  • A Swift solution can be found at https://stackoverflow.com/questions/64201384/why-does-uigraphicsgetcurrentcontext-return-nil-after-uigraphicsbeginimagecontex/ – XY L Oct 05 '20 at 03:53

1 Answers1

4

You can just create a subclass of UILabel that creates the blur effect.

Here is a boiler template:

BlurredUILabel.h

#import <UIKit/UIKit.h>

@interface BlurredUILabel : UILabel

@property (nonatomic, readwrite) IBInspectable CGFloat blurRadius;

@end

BlurredUILabel.m

#import "BlurredUILabel.h"

@implementation BlurredUILabel

- (void)setText:(NSString *)text {
    super.text = text;
    UIGraphicsBeginImageContext(self.bounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [blurFilter setDefaults];

    CIImage *imageToBlur = [CIImage imageWithCGImage:image.CGImage];
    [blurFilter setValue:imageToBlur forKey:kCIInputImageKey];
    [blurFilter setValue:@(self.blurRadius) forKey:@"inputRadius"];

    CIImage *outputImage = blurFilter.outputImage;
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];

    [self.layer setContents:(__bridge id)cgimg];
    CGImageRelease(cgimg);
}

@end

And you would use it like this:

#import "TestViewController.h"
#import "BlurredUILabel.h"

@interface TestViewController ()

@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    BlurredUILabel *label = [[BlurredUILabel alloc] initWithFrame:CGRectMake(50, 50, 300, 50)];
    label.blurRadius = 2.0;
    label.backgroundColor = [UIColor redColor];
    label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:35];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = @"HELLO";
    [self.view addSubview:label];

    label.blurRadius = 1.5;
    [label performSelector:@selector(setText:) withObject:@"Test new string" afterDelay:2];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
Lefteris
  • 14,550
  • 2
  • 56
  • 95
  • Thanks Lefteris, I will try this solllution. – Ravi Gautam May 19 '15 at 06:39
  • 1
    BTW, be careful when blurring using Core Image to note that the resulting image is larger than the original image. This can result in undesirable shifting of the blurred image when you `setContents`. You can prevent that by using `[imageToBlur extent]` when calling `createCGImage` (or otherwise create centered `CGRect` within `[outputImage extent]` of the right size). – Rob May 19 '15 at 21:29
  • Thanks Lefteris, is there a way to roll back the status of the label? I don't know.. maybe removing cgimg from the layer.contents?! – marco.marinangeli Dec 14 '15 at 23:56
  • I would just add a Boolean instance variable in the subclass as a flag and when it was set to yes I would not do the blur in the setText function.... Then I would turn the flag on before setting the text without blur and turn it off when I wanted blur again – Lefteris Dec 15 '15 at 08:08
  • This is not working. Has anyone had luck here? – Drew Burnett Apr 06 '17 at 02:50
  • If you need a Swift solution, The question got answered here, https://stackoverflow.com/questions/64201384/why-does-uigraphicsgetcurrentcontext-return-nil-after-uigraphicsbeginimagecontex/ – XY L Oct 05 '20 at 03:53