How to replicate the blurred text in Notification Center (iOS 8)

前端 未结 5 1020
情深已故
情深已故 2020-12-04 18:27

I am playing with TodayExtension in iOS 8 and I wondered how to apply that blur effect to the Text or to buttons. I already figured out that it has something to do with UIVi

相关标签:
5条回答
  • 2020-12-04 18:41

    The "Bearbeiten" button can be recreated by drawing a see through text on the button. How to do this has been answered in this post.

    Please see below for my solution. The original iOS "Bearbeiten" still looks a bit different. I've made it look similar by changing the alpha. Not the right solution. Hope that this post will trigger someone to find the correct way to do it (and share it).

    In viewDidLoad:

    _pinButton.backgroundColor = [UIColor clearColor];
    _pinButton.layer.cornerRadius = 4.0;
    _pinButton.clipsToBounds = YES;
    
    UIColor *white = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.75];
    UIColor *whiteT = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.3];
    UIFont *buttonFont = [UIFont fontWithName:@"HelveticaNeue" size:12.0];
    
    [_pinButton setImage:[self imageWithCutOutString:@"Pin" 
                                                size:_pinButton.frame.size 
                                     backgroundColor:white 
                                                font:buttonFont] 
                forState:UIControlStateNormal];
    
    [_pinButton setImage:[self imageWithCutOutString:@"Pin" 
                                                size:_pinButton.frame.size 
                                     backgroundColor:whiteT 
                                                font:buttonFont]
                forState:UIControlStateHighlighted];
    

    And the actual imageWithCutOutString method itself:

    - (UIImage *)imageWithCutOutString:(NSString *)string size:(CGSize)size backgroundColor:(UIColor *)backgroundColor font:(UIFont *)font
    {
        NSDictionary *textAttributes = @{ NSFontAttributeName:font };
    
        CGSize textSize = [string sizeWithAttributes:textAttributes];
    
        UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]);
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(ctx, backgroundColor.CGColor);
    
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0.0, 0.0, size.width, size.height)];
        CGContextAddPath(ctx, path.CGPath);
        CGContextFillPath(ctx);
    
        CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut);
        CGPoint center = CGPointMake((size.width - textSize.width) / 2.0, (size.height - textSize.height) / 2.0);
        [string drawAtPoint:center withAttributes:textAttributes];
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    
    0 讨论(0)
  • 2020-12-04 18:47

    You are actually looking at two effects here. The background has a blur effect applied and the labels have a vibrancy effect applied.

    For the blur effect you first initialize a UIBlurEffect with a style (dark, light, extra light):

    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    

    For the vibrancy effect you initialize a UIVibrancyEffect with the blur effect you just created:

    UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
    

    This is because the vibrancy effect needs to take the underlying blur effect into account.

    Next you create two UIVisualEffectViews:

    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
    

    These need to be added to the view hierarchy. UIVisualEffectView has a contentView property to which you must add subviews to which you want the respective effect applied. Ensure that vibrancyEffectView is added over, or as a subview of the contentView of, the blurEffectView.

    You can also set all this up in IB (I'm using Xcode 6 beta 5). There is a "Visual Effect View with Blur" and a "Visual Effect Views with Blur and Vibrancy" in the Object Library that you can drag to a view. The "Visual Effect Views with Blur and Vibrancy" sets up two UIVisualEffectViews nested as described above.

    Check out WWDC14 Session 221 and the UIVisualEffectView.h header for more info.

    0 讨论(0)
  • 2020-12-04 18:54

    I was able to achieve the "Bearbeiten" button using AYVibrantButton with the AYVibrantButtonStyleFill style:

    // Create the button
    AYVibrantButton* moreButton = [[AYVibrantButton alloc] initWithFrame:CGRectMake(0, 0, 210, 30) style:AYVibrantButtonStyleFill];
    // Set the vibrancy effect to the one provided by notification center
    moreButton.vibrancyEffect = [UIVibrancyEffect notificationCenterVibrancyEffect];
    // Setup basic button properties
    moreButton.text = @"Show More..";
    moreButton.font = [UIFont systemFontOfSize:13.0];
    // Add it to your view
    [self.view addSubview:moreButton];
    
    0 讨论(0)
  • 2020-12-04 19:00

    Updated Answer for iOS 10

    In iOS 10, you can use widgetPrimaryVibrancyEffect and widgetSecondaryVibrancyEffect to automatically return a UIVibrancyEffect object.

    Check out the documentation here and here.

    Answer for iOS 9

    Use this code to apply a vibrancy effect to your whole widget:

    UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:[UIVibrancyEffect notificationCenterVibrancyEffect]];
    effectView.frame = self.view.bounds
    effectView.autoresizingMask = self.view.autoresizingMask;
    
    __strong UIView *oldView = self.view;
    
    self.view = effectView;
    
    [effectView.contentView addSubview:oldView];
    
    self.view.tintColor = [UIColor clearColor];
    
    0 讨论(0)
  • 2020-12-04 19:02

    I have tried the examples above but none of them seemed working out of the box. Here is a similar example which works for me:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIVibrancyEffect *effect = [UIVibrancyEffect notificationCenterVibrancyEffect];
    
        UIVisualEffectView *outer = [[UIVisualEffectView alloc] initWithEffect:effect];
        outer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        outer.frame = self.view.bounds;
    
        UIVisualEffectView *inner = [[UIVisualEffectView alloc] initWithEffect:effect];
        inner.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        inner.frame = self.view.bounds;
    
        UILabel *label = [UILabel new];
        label.text = @"HELLO, I am a vibrant label";
        label.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        label.frame = self.view.bounds;
    
        [inner.contentView addSubview:label];
        [outer.contentView addSubview:inner];
        [self.view addSubview:outer];
    }
    
    0 讨论(0)
提交回复
热议问题