iOS_自訂毛半透明效果

來源:互聯網
上載者:User

標籤:ios   毛玻璃   上下文   

最終:







關鍵代碼:




UIImage分類代碼

////  UIImage+BlurGlass.h//  帥哥_團購////  Created by beyond on 14-8-30.//  Copyright (c) 2014年 com.beyond. All rights reserved.//  毛半透明效果 UIImage分類#import <UIKit/UIKit.h>@interface UIImage (BlurGlass)/* 1.白色,參數: 透明度 0~1,  0為白,   1為深灰色 半徑:預設30,推薦值 3   半徑值越大越模糊 ,值越小越清楚 色彩飽和度(濃度)因子:  0是黑白灰, 9是濃彩色, 1是原色  預設1.8 “彩度”,英文是稱Saturation,即飽和度。將無彩色的黑白灰定為0,最鮮豔定為9s,這樣大致分成十階段,讓數值和人的感官直覺一致。 */- (UIImage *)imgWithLightAlpha:(CGFloat)alpha radius:(CGFloat)radius colorSaturationFactor:(CGFloat)colorSaturationFactor;// 2.封裝好,供外界調用的- (UIImage *)imgWithBlur;@end


////  UIImage+BlurGlass.m//  帥哥_團購////  Created by beyond on 14-8-30.//  Copyright (c) 2014年 com.beyond. All rights reserved.//#import "UIImage+BlurGlass.h"#import <Accelerate/Accelerate.h>@implementation UIImage (BlurGlass)/*   1.白色,參數:    透明度 0~1,  0為白,   1為深灰色    半徑:預設30,推薦值 3   半徑值越大越模糊 ,值越小越清楚    色彩飽和度(濃度)因子:  0是黑白灰, 9是濃彩色, 1是原色  預設1.8    “彩度”,英文是稱Saturation,即飽和度。將無彩色的黑白灰定為0,最鮮豔定為9s,這樣大致分成十階段,讓數值和人的感官直覺一致。 */- (UIImage *)imgWithLightAlpha:(CGFloat)alpha radius:(CGFloat)radius colorSaturationFactor:(CGFloat)colorSaturationFactor{    UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:alpha];    return [self imgBluredWithRadius:radius tintColor:tintColor saturationDeltaFactor:colorSaturationFactor maskImage:nil];}// 2.封裝好,供外界調用的- (UIImage *)imgWithBlur{    // 調用方法1   return [self imgWithLightAlpha:0.1 radius:3 colorSaturationFactor:1];}// 內部方法,核心代碼,封裝了毛半透明效果 參數:半徑,顏色,色彩飽和度- (UIImage *)imgBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage{            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) {            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();    }        // 開啟上下文 用於輸出映像    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);    CGContextRef outputContext = UIGraphicsGetCurrentContext();    CGContextScaleCTM(outputContext, 1.0, -1.0);    CGContextTranslateCTM(outputContext, 0, -self.size.height);        // 開始畫底圖    CGContextDrawImage(outputContext, imageRect, self.CGImage);        // 開始畫模糊效果    if (hasBlur) {        CGContextSaveGState(outputContext);        if (maskImage) {            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);        }        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);        CGContextRestoreGState(outputContext);    }        // 添加顏色渲染    if (tintColor) {        CGContextSaveGState(outputContext);        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);        CGContextFillRect(outputContext, imageRect);        CGContextRestoreGState(outputContext);    }        // 輸出成品,並關閉上下文    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();        return outputImage;}@end

控制器代碼

////  MineController.m//  帥哥_團購////  Created by beyond on 14-8-14.//  Copyright (c) 2014年 com.beyond. All rights reserved.//  dock上面的【我的】按鈕對應的控制器#import "MineController.h"#import "ImgDownloadTool.h"#import <Accelerate/Accelerate.h>#import "UIImage+BoxBlur.h"#import "GirlCell.h"// 每一個格子的寬和高#define kItemW 240#define kItemH 320@interface MineController ()<UICollectionViewDataSource,UICollectionViewDelegate>{    NSMutableArray *_imgArr;    UIWebView *_webView;        // 添加一個coverImgView,用於點擊了cell時,進行螢幕並加上毛半透明效果,置於最上方作為蒙板        UIImageView *_coverBlurImgView;    // 點擊cell,彈出一個大圖(必須在控制器顯示之前 再確定frame,真實的frame)    UIImageView *_showingImgView;}@end@implementation MineController#pragma mark - 生命週期方法- (void)viewDidLoad{    [super viewDidLoad];    self.title = @"我的青春誰做主";    // 0.載入plist檔案儲存的url數組    // sg_bundle模板代碼,1,獲得.app主要的包;2,返回主要的包中某個檔案的fullPath全路徑    NSBundle *mainBundle = [NSBundle mainBundle];    NSString *fullPath = [mainBundle pathForResource:@"sinaImgArr.plist" ofType:nil];    _imgArr = [NSArray arrayWithContentsOfFile:fullPath];                    // 1.建立自己的collectionView    [self addCollectionView];        // 2.註冊cell格子要用到的xib檔案    [self.collectionView registerNib:[UINib nibWithNibName:@"GirlCell" bundle:nil] forCellWithReuseIdentifier:@"GirlCell"];        // 3.設定collectionView永遠支援垂直滾動,為下拉重新整理準備(彈簧)    self.collectionView.alwaysBounceVertical = YES;        // 4.設定collectionView的背景色    self.collectionView.backgroundColor = kGlobalBg;        // 5.添加一個coverImgView,用於點擊了cell時,進行螢幕並加上毛半透明效果,置於最上方作為蒙板    _coverBlurImgView = [[UIImageView alloc]init];    [self.view addSubview:_coverBlurImgView];            // 6.點擊cell,彈出一個大圖(必須在控制器顯示之前 再確定frame,真實的frame)    _showingImgView = [[UIImageView alloc]init];    _showingImgView.backgroundColor = [UIColor clearColor];    [self.view addSubview:_showingImgView];    _showingImgView.contentMode = UIViewContentModeScaleAspectFit;    _showingImgView.userInteractionEnabled = YES;    [_showingImgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showingImgTap)]];}// 1.建立自己的collectionView- (void)addCollectionView{    // 建立一個流布局,必須指定    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];    // 設定流布局裡面的每一個格子寬和高,即每一個網格的尺寸    layout.itemSize = CGSizeMake(kItemW, kItemH);    // 每一行之間的間距    layout.minimumLineSpacing = 20;    // 指定的流布局建立一個collectionView,並且用成員變數記住    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];    // 高度和寬度自動調整    self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;    self.collectionView.delegate = self;    self.collectionView.dataSource = self;    [self.view addSubview:self.collectionView];}#pragma mark 在viewWillAppear和viewDidAppear中可以取得view最準確的寬高(width和height)// 重要~~~因為在控制器建立時,寬預設是768,高預設是1024,不管橫豎屏// 只有在viewWillAppear和viewDidAppear方法中,可以取得view最準確的(即實際的)寬和高(width和height)- (void)viewWillAppear:(BOOL)animated{    // 預設計算layout    [self didRotateFromInterfaceOrientation:0];}#pragma mark - 父類方法// 攔截,螢幕即將旋轉的時候調用(控制器監控旋轉螢幕)- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{    //log(@"螢幕即將旋轉");}#pragma mark 旋轉螢幕完畢的時候調用// 攔截,旋轉螢幕完畢的時候調用- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{    // 1.取出建立CollectionViewController時傳入的的UICollectionViewFlowLayout    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;            // 2.計算間距    CGFloat v = 0;    CGFloat h = 0;    CGFloat height = self.view.frame.size.height -44;    CGFloat width = self.view.frame.size.width;    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)        ) {        // 橫屏的間距        v = (height - 2 * kItemH) / 3;        h = (width - 3 * kItemW) / 4;            } else {        // 豎屏的間距        v = (height - 3 * kItemH) / 4;        h = (width - 2 * kItemW) / 3;    }    // 3.動畫調整格子之間的距離    [UIView animateWithDuration:4.0 animations:^{        // 上 左 下 右 四個方向的margin        layout.sectionInset = UIEdgeInsetsMake(h, h, v, h);        // 每一行之間的間距        layout.minimumLineSpacing = h;    }];        // 4.旋轉完成之後,才可以得到真實的frame,暫時隱藏起來,當點擊cell的時侯才展示  -5    _coverBlurImgView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);    _coverBlurImgView.hidden = YES;            _showingImgView.hidden = YES;    CGRect temp =     _showingImgView.frame;    CGFloat x =self.view.frame.size.width * 0.5;    CGFloat y =self.view.frame.size.height * 0.5;    temp = CGRectMake(x,y, 0, 0);    _showingImgView.frame = temp;}#pragma mark - collectionView代理方法// 共有多少個Item(就是格子Cube),詢問子類- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{    return _imgArr.count;}#pragma mark 重新整理資料的時候會調用(reloadData)#pragma mark 每當有一個cell重新進入螢幕視野範圍內就會調用// 產生每一個獨一無二的格子,詢問子類- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"GirlCell";    GirlCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];        cell.imgSrc = _imgArr[indexPath.row];        return cell;}// 點擊了一個格子時,1,截屏,2,動畫毛玻璃圖片,3,showing從小放到大- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{        // 1,截屏    [self screenShot];    // 2,顯示    _coverBlurImgView.alpha = 1;     _coverBlurImgView.hidden = NO;        // 3.調用UIImage的分類方法,進行毛玻璃處理    _coverBlurImgView.image = [_coverBlurImgView.image imgWithBlur];    // 4.展示_showingImgView    _showingImgView.hidden = NO;            // 點擊cell,彈出一個大圖    CGRect temp =     _showingImgView.frame;    CGFloat x =self.view.frame.size.width * 0.5;    CGFloat y =self.view.frame.size.height * 0.5;    temp = CGRectMake(x,y, 0, 0);    _showingImgView.frame = temp;    _showingImgView.alpha = 0;    [UIView animateWithDuration:0.5 animations:^{          [ImgDownloadTool imgDownloadWithUrl:_imgArr[indexPath.row] tmpImgName:kImgPlaceHolder imageView:_showingImgView];        _showingImgView.alpha = 1;        _showingImgView.frame = self.view.bounds;    }];    }// 使用上下文,並使用指定的地區裁剪,模板代碼- (void)screenShot{    // 將要被的view    // 背景圖片 總的大小    CGSize size = self.view.frame.size;    UIGraphicsBeginImageContext(size);    // 開啟上下文,使用參數之後,截出來的是原圖(YES  0.0 品質高)    UIGraphicsBeginImageContextWithOptions(size, YES, 0.0);    // 裁剪的關鍵代碼,要裁剪的矩形範圍    CGRect rect = CGRectMake(0, 0, size.width, size.height  );    //註:iOS7以後renderInContext:由drawViewHierarchyInRect:afterScreenUpdates:替代    [self.view drawViewHierarchyInRect:rect  afterScreenUpdates:NO];    // 從上下文中,取出UIImage    UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();    // 添加截取好的圖片到圖片View裡面    _coverBlurImgView.image = snapshot;        // 千萬記得,結束上下文(移除棧頂上下文)    UIGraphicsEndImageContext();    }// 正在顯示的大圖被點了- (void)showingImgTap{                [UIView animateWithDuration:0.5 animations:^{        CGRect temp =     _showingImgView.frame;        CGFloat x =self.view.frame.size.width * 0.5;        CGFloat y =self.view.frame.size.height * 0.5;        temp = CGRectMake(x,y, 0, 0);        _showingImgView.frame = temp;        _showingImgView.alpha = 0;    } completion:^(BOOL finished) {        // 隱藏起來        _showingImgView.hidden = YES;                _coverBlurImgView.hidden = YES;    }];}#pragma mark - 生命週期方法- (void)dealloc{    [[NSNotificationCenter defaultCenter] removeObserver:self];}@end









iOS_自訂毛半透明效果

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.