先來看看效果圖,由於錄屏軟件不給力,毛玻璃效果不明顯,請見諒。
步驟詳解:
說下思路,很簡單,首先自定義一個collectionView
, 重寫它的initWithFrame:collectionViewLayout:
方法,在這裡面做配置,這裡用的是AXECollectionView
.
與之對應的自定義一個collectionViewCell
,在cell
裡配置操作:設置layer
塗層,加載圖片等操作,這裡用的是AXECollectionViewCell
.
最後在需要展示的控制器裡調用AXECollectionView
,給它傳入一個自定義的流水布局和圖片數組,大功告成.
示例代碼如下:
// viewController @interface ViewController () @property (nonatomic, strong) AXECollectionView *collectionView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 流水布局 UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; flowLayout.minimumLineSpacing = kItem_Margin; flowLayout.minimumInteritemSpacing = [UIScreen mainScreen].bounds.size.height; flowLayout.itemSize = CGSizeMake([UIScreen mainScreen].bounds.size.width - kItem_Margin, kItem_Height); flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; flowLayout.sectionInset = UIEdgeInsetsMake(0, kItem_Margin / 2, 0, kItem_Margin / 2); CGRect frame = self.view.bounds; _collectionView = [[AXECollectionView alloc] initWithFrame:frame collectionViewLayout:flowLayout]; // 傳入圖片數組 _collectionView.imgArr = @[ @"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", ]; [self.view addSubview:_collectionView]; } // AXECollectionView.h @interface AXECollectionView : UICollectionView @property (nonatomic, strong) NSArray *imgArr; @end // AXECollectionView.m @interface AXECollectionView () <UICollectionViewDelegate, UICollectionViewDataSource> // 背景imgView @property (nonatomic, strong) UIImageView *bgImgView; @end @implementation AXECollectionView static NSString *const AXECollectionViewCellID = @"AXECollectionViewCell"; - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { if(self = [super initWithFrame:frame collectionViewLayout:layout]) { [self setup]; } return self; } - (void)setup { self.showsVerticalScrollIndicator = NO; self.showsHorizontalScrollIndicator = NO; self.pagingEnabled = YES; self.dataSource = self; self.delegate = self; [self registerClass:[AXECollectionViewCell class] forCellWithReuseIdentifier:AXECollectionViewCellID]; // collectionView背景view UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:self.bounds]; self.backgroundView = bgImgView; self.bgImgView = bgImgView; // 毛玻璃效果 (iOS8.0以後適用) UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; effectView.frame = self.bounds; [self.backgroundView addSubview:effectView]; } #pragma mark - UICollectionViewDataSource - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { AXECollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:AXECollectionViewCellID forIndexPath:indexPath]; cell.img = self.imgArr[indexPath.row]; // 設置毛玻璃圖片 self.bgImgView.image = [UIImage imageNamed:self.imgArr[indexPath.row]]; return cell; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.imgArr.count; } #pragma mark - UICollectionViewDelegate - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath { AXECollectionViewCell *myCell = (AXECollectionViewCell *)cell; [UIView animateWithDuration:0.5 animations:^{ myCell.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.4); }]; }
補充一下
例子中我是用的UIBlurEffect
做的毛玻璃效果,這個是iOS8以後出現的,如果你要適配7的系統,那就要另做配置.
如果不用UIBlurEffect
的話,下面這兩種同樣能做出模糊效果,只不過第一種性能較差,建議大家按需使用.
// 返回濾鏡處理後圖片 - (UIImage *)coreBlurImage:(UIImage *)image withBlurNumber:(CGFloat)blur { CIContext *context = [CIContext contextWithOptions:nil]; CIImage *inputImage= [CIImage imageWithCGImage:image.CGImage]; // 設置filter CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"]; [filter setValue:inputImage forKey:kCIInputImageKey]; [filter setValue:@(blur) forKey: @"inputRadius"]; // 模糊圖片 CIImage *result=[filter valueForKey:kCIOutputImageKey]; CGImageRef outImage=[context createCGImage:result fromRect:[result extent]]; UIImage *blurImage=[UIImage imageWithCGImage:outImage]; CGImageRelease(outImage); return blurImage; } // 返回高斯效果模糊圖片 - (UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur { if (blur < 0.f || blur > 1.f) { blur = 0.5f; } int boxSize = (int)(blur * 40); boxSize = boxSize - (boxSize % 2) + 1; CGImageRef img = image.CGImage; vImage_Buffer inBuffer, outBuffer; vImage_Error error; void *pixelBuffer; // 從CGImage中獲取數據 CGDataProviderRef inProvider = CGImageGetDataProvider(img); CFDataRef inBitmapData = CGDataProviderCopyData(inProvider); // 設置從CGImage獲取對象的屬性 inBuffer.width = CGImageGetWidth(img); inBuffer.height = CGImageGetHeight(img); inBuffer.rowBytes = CGImageGetBytesPerRow(img); inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData); pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img)); if(pixelBuffer == NULL) NSLog(@"No pixelbuffer"); outBuffer.data = pixelBuffer; outBuffer.width = CGImageGetWidth(img); outBuffer.height = CGImageGetHeight(img); outBuffer.rowBytes = CGImageGetBytesPerRow(img); error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend); if (error) { NSLog(@"error from convolution %ld", error); } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef ctx = CGBitmapContextCreate( outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes, colorSpace, kCGImageAlphaNoneSkipLast); CGImageRef imageRef = CGBitmapContextCreateImage (ctx); UIImage *returnImage = [UIImage imageWithCGImage:imageRef]; // clean up CGColorSpaceRelease(colorSpace); free(pixelBuffer); CFRelease(inBitmapData); CGColorSpaceRelease(colorSpace); CGImageRelease(imageRef); return returnImage; }
總結
以上就是iOS自定義collectionView實現毛玻璃效果的全部內容,希望能對各位iOS開發者們有一定的幫助,如果有疑問大家可以留言交流,謝謝大家對本站的支持。