时间:2021-05-04 10:47:20 | 栏目:iOS代码 | 点击:次
先来看看效果图,由于录屏软件不给力,毛玻璃效果不明显,请见谅。
步骤详解:
说下思路,很简单,首先自定义一个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; }
总结