iOS通知栏磨砂透明背景的代码实现(高斯模糊)

方法一.使用UIToolBar可以支持iOS7之后的高斯模糊效果

利用UIToolbar来实现是最简单的毛玻璃效果。需要什么控件自行添加到toolbar上就OK。

初始化UIToolbar,设置toolbar样式为UIBarStyleBlackTranslucent或者UIBarStyleBlackOpaque 即可。修改bartintcolor的RGB值 可修改毛玻璃色调效果。

通过本人亲身尝试,其实UIToolBar,UINavigationBar,UITabbar在IOS7上都会有高斯效果,当然,有些机型不支持(后面会总结),然后他们的表现都是一模一样的,细微的差别就是各个控件上的边框多了一些圆角,横线,但是实现高斯效果的类都是用同一个。具体是什么类,可以去研究一下,这里不深入介绍那个类,只讲怎么使用
高斯效果有系统提供的有两种效果,白色底和黑色底。具体通过设置UIBarStyle属性去设置,有UIBarStyleDefault和UIBarStyleBlack,这两种效果对比起来,Black的效果最佳,所以现在在系统本身,都是用Black样式。
但是有人想,如果只有这两种样式,能不能通过修改一些属性去改变样式呢。下面尝试了几种方法
1.alpha值
通过修改alpha值,发现,如果alpha值不为1,那么就没有高斯效果,假如你对UIToolbar进行alpha值渐变,你会发现只有等到为1的时候才会有效果,所以alpha值不能修改,会导致高斯模糊失效
2.mask
由于UIToolbar只有是矩形的样式,我们可以通过mask属性对图像进行处理,通过根据我们自定的图形,mask对应的图形,但是,如果你使用了mask,那么很不好意思,高斯模糊没有了。
3.tintColor
设置了没效果
4.barTintColor
这个是设置bar 背景颜色,设置之后,发现有效果,但是效果不明显,有兴趣可以设置一下
至于其他属性,有兴趣可以去设置一下,我是没找到其他属性了

根据好几天的接触,发现了IOS7的高斯模糊的一个特点,由于系统是支持实时更新,这部分运算明显是有效率问题的,但是我们发现,系统的好像感觉不到效率问题。通过观察,发现,如果背景图片颜色比较单一,简单,高斯模糊效果很一般,有时候就只是简单的alpha透明过去,如果背景颜色块比较明显,那么高斯效果就很清晰,可见苹果对这个的处理还是做了优化,而不是每时每刻都在刷新界面,不然效率肯定提不上来。
机型限制,目前只支持IOS7系统,4s和以上的机型,touch5, ipad上屏幕较大,支持ipad4以上

示例代码:

@property (weak, nonatomic) IBOutlet UIToolbar *bottomTabsBarBlurBgView;
@property (weak, nonatomic) IBOutlet SingleSelectTabsView *bottomTabsBar;


- (void)awakeFromNib
{
    [super awakeFromNib];

    self.bottomTabsBarBlurBgView.barStyle = UIBarStyleBlack;
    self.bottomTabsBarBlurBgView.hidden = IS_AT_LEAST_IOS7 ? NO : YES;
    self.bottomTabsBar.alpha = IS_AT_LEAST_IOS7 ? 1 : 0.95;
    self.bottomTabsBar.backgroundColor = IS_AT_LEAST_IOS7 ? UIColorFromRGB(255, 255, 255, 0) : UIColorFromRGB(25, 25, 25, 1);

}






方法二.通过图片处理+实时刷新的方法实现(但是有性能问题)

(1).工程中添加Accelerate.framework。

(2).添加Category文件UIImage+ImageEffects.h/UIImage+ImageEffects.m.

#import <UIKit/UIKit.h>

@interface UIImage (ImageEffects)

- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;

- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;

@end

#import "UIImage+ImageEffects.h"

#import <Accelerate/Accelerate.h>
#import <float.h>


@implementation UIImage (ImageEffects)


- (UIImage *)applyLightEffect
{
    UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
    return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
}


- (UIImage *)applyExtraLightEffect
{
    UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
    return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
}


- (UIImage *)applyDarkEffect
{
    UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
    return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
}


- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor
{
    const CGFloat EffectColorAlpha = 0.6;
    UIColor *effectColor = tintColor;
    int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
    if (componentCount == 2) {
        CGFloat b;
        if ([tintColor getWhite:&b alpha:NULL]) {
            effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
        }
    }
    else {
        CGFloat r, g, b;
        if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
            effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
        }
    }
    return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
}


- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
{
    // Check pre-conditions.
    if (self.size.width < 1 || self.size.height < 1) {
        NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
        return nil;
    }
    if (!self.CGImage) {
        NSLog (@"*** error: image must be backed by a CGImage: %@", self);
        return nil;
    }
    if (maskImage && !maskImage.CGImage) {
        NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
        return nil;
    }
    
    CGRect imageRect = { CGPointZero, self.size };
    UIImage *effectImage = self;
    
    BOOL hasBlur = blurRadius > __FLT_EPSILON__;
    BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
    if (hasBlur || hasSaturationChange) {
        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
        CGContextRef effectInContext = UIGraphicsGetCurrentContext();
        CGContextScaleCTM(effectInContext, 1.0, -1.0);
        CGContextTranslateCTM(effectInContext, 0, -self.size.height);
        CGContextDrawImage(effectInContext, imageRect, self.CGImage);
        
        vImage_Buffer effectInBuffer;
        effectInBuffer.data     = CGBitmapContextGetData(effectInContext);
        effectInBuffer.width    = CGBitmapContextGetWidth(effectInContext);
        effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);
        effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);
        
        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
        CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
        vImage_Buffer effectOutBuffer;
        effectOutBuffer.data     = CGBitmapContextGetData(effectOutContext);
        effectOutBuffer.width    = CGBitmapContextGetWidth(effectOutContext);
        effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);
        effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);
        
        if (hasBlur) {
            // A description of how to compute the box kernel width from the Gaussian
            // radius (aka standard deviation) appears in the SVG spec:
            // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
            //
            // For larger values of 's' (s >= 2.0), an approximation can be used: Three
            // successive box-blurs build a piece-wise quadratic convolution kernel, which
            // approximates the Gaussian kernel to within roughly 3%.
            //
            // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
            //
            // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
            //
            CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
            NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
            if (radius % 2 != 1) {
                radius += 1; // force radius to be odd so that the three box-blur methodology works.
            }
            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
            vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
        }
        BOOL effectImageBuffersAreSwapped = NO;
        if (hasSaturationChange) {
            CGFloat s = saturationDeltaFactor;
            CGFloat floatingPointSaturationMatrix[] = {
                0.0722 + 0.9278 * s,  0.0722 - 0.0722 * s,  0.0722 - 0.0722 * s,  0,
                0.7152 - 0.7152 * s,  0.7152 + 0.2848 * s,  0.7152 - 0.7152 * s,  0,
                0.2126 - 0.2126 * s,  0.2126 - 0.2126 * s,  0.2126 + 0.7873 * s,  0,
                0,                    0,                    0,  1,
            };
            const int32_t divisor = 256;
            NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
            int16_t saturationMatrix[matrixSize];
            for (NSUInteger i = 0; i < matrixSize; ++i) {
                saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
            }
            if (hasBlur) {
                vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
                effectImageBuffersAreSwapped = YES;
            }
            else {
                vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
            }
        }
        if (!effectImageBuffersAreSwapped)
            effectImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        if (effectImageBuffersAreSwapped)
            effectImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
    // Set up output context.
    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
    CGContextRef outputContext = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(outputContext, 1.0, -1.0);
    CGContextTranslateCTM(outputContext, 0, -self.size.height);
    
    // Draw base image.
    CGContextDrawImage(outputContext, imageRect, self.CGImage);
    
    // Draw effect image.
    if (hasBlur) {
        CGContextSaveGState(outputContext);
        if (maskImage) {
            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
        }
        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
        CGContextRestoreGState(outputContext);
    }
    
    // Add in color tint.
    if (tintColor) {
        CGContextSaveGState(outputContext);
        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
        CGContextFillRect(outputContext, imageRect);
        CGContextRestoreGState(outputContext);
    }
    
    // Output image is ready.
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return outputImage;
}


@end


(3).使用Sample代码(图片可以通过截屏背景得到,从而有磨砂透明的盖层效果)。————>苹果官方Demo<————

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    const CGFloat fontSize = 25.f;
    const NSString *text = @"Over layer string.";
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir Next" size:fontSize]}];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 200, size.width, size.height)];
    label.font = [UIFont fontWithName:@"Avenir Next" size:fontSize];
    label.textAlignment = NSTextAlignmentNatural;
    label.backgroundColor = [UIColor clearColor];
    label.text = (NSString *)text;
    
    UIImage *image = [UIImage imageNamed:@"wat.png"];
    UIImage *blurredImage = [image applyBlurWithRadius:10 tintColor:[UIColor colorWithWhite:0 alpha:0.25] saturationDeltaFactor:1.f maskImage:nil];
    
    UIImageView *imageView = [[UIImageView alloc] initWithImage:blurredImage];
    imageView.frame = CGRectMake(0, 0, 500, 375);
    
    CGFloat imgScale = image.scale;
    CGRect labelFrame = label.frame;
    CGRect realRect = CGRectMake(labelFrame.origin.x * imgScale, labelFrame.origin.y * imgScale, labelFrame.size.width * imgScale, labelFrame.size.height * imgScale);
    CGImageRef labelPatternImage = CGImageCreateWithImageInRect(image.CGImage, realRect);
    label.textColor = [UIColor colorWithPatternImage:[UIImage imageWithCGImage:labelPatternImage scale:image.scale orientation:UIImageOrientationUp]];
    CGImageRelease(labelPatternImage);
    
    [self.view addSubview:imageView];
    [self.view addSubview:label];
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用以下代码实现 iOS 按钮的背景渐变色:CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = self.btn.bounds; gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil]; [self.btn.layer insertSublayer:gradient atIndex:0]; ### 回答2: iOS按钮背景渐变色可以通过以下步骤使用OC代码实现: 1. 导入渐变色所需的头文件: ```objc #import <QuartzCore/QuartzCore.h> ``` 2. 创建按钮: ```objc UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 200, 50)]; [self.view addSubview:myButton]; ``` 3. 创建渐变色图层: ```objc CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = myButton.bounds; ``` 4. 设置渐变色图层的颜色: ```objc gradient.colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor blueColor].CGColor]; ``` 5. 设置渐变色方向: ```objc // 横向渐变 gradient.startPoint = CGPointMake(0, 0.5); gradient.endPoint = CGPointMake(1, 0.5); // 纵向渐变 // gradient.startPoint = CGPointMake(0.5, 0); // gradient.endPoint = CGPointMake(0.5, 1); ``` 6. 将渐变色图层添加到按钮的背景图层中: ```objc [myButton.layer insertSublayer:gradient atIndex:0]; ``` 7. 最后,可以给按钮设置一些其他属性,如标题、字体等: ```objc [myButton setTitle:@"渐变按钮" forState:UIControlStateNormal]; [myButton.titleLabel setFont:[UIFont systemFontOfSize:17]]; [myButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; ``` 通过以上步骤,即可通过OC代码实现iOS按钮的背景渐变色效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值