当前位置: 首页 > 编程笔记 >

iOS自定义collectionView实现毛玻璃效果

乌翔
2023-03-14
本文向大家介绍iOS自定义collectionView实现毛玻璃效果,包括了iOS自定义collectionView实现毛玻璃效果的使用技巧和注意事项,需要的朋友参考一下

先来看看效果图,由于录屏软件不给力,毛玻璃效果不明显,请见谅。

步骤详解:

说下思路,很简单,首先自定义一个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开发者们有一定的帮助,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。

 类似资料:
  • 本文向大家介绍Android实现毛玻璃效果的对话框,包括了Android实现毛玻璃效果的对话框的使用技巧和注意事项,需要的朋友参考一下 一个popwindow,在弹出的时候背景是原界面的截图加高斯模糊效果: 先给出popwindow的布局文件 里面那个自定义imageView控件在我上一篇博客里,下面是activity的布局 用于圆角的背景xml,放在drawable文件夹中 activity的源

  • 本文向大家介绍OpenCV实现马赛克和毛玻璃滤镜效果,包括了OpenCV实现马赛克和毛玻璃滤镜效果的使用技巧和注意事项,需要的朋友参考一下 本文为大家分享了OpenCV实现马赛克和毛玻璃滤镜的具体代码,供大家参考,具体内容如下 一、马赛克效果 马赛克的实现原理是把图像上某个像素点一定范围邻域内的所有点用邻域内随机选取的一个像素点的颜色代替,这样可以模糊细节,但是可以保留大体的轮廓。 以下OpenC

  • 本文向大家介绍Android中实现毛玻璃效果的3种方法,包括了Android中实现毛玻璃效果的3种方法的使用技巧和注意事项,需要的朋友参考一下 最近在做一款叫叽叽的App(男银懂的),其中有一个功能需要对图片处理实现毛玻璃的特效 进过一番预研,找到了3中实现方案,其中各有优缺点: 1、如果系统的api在16以上,可以使用系统提供的方法直接处理图片 2、 如果Api条件不满足,可以使用如下方法 3、

  • 本文向大家介绍Android毛玻璃背景效果简单实现代码,包括了Android毛玻璃背景效果简单实现代码的使用技巧和注意事项,需要的朋友参考一下 思路:      1.使用findViewByid获得需要设置毛玻璃的控件。      2.调用 setBlurBackground(Bitmap bmp)方法(下面会给出),参数为Bitmap类型,给控件设置毛玻璃背景!      3.已完成, 方法:

  • 本文向大家介绍Android模糊处理实现图片毛玻璃效果,包括了Android模糊处理实现图片毛玻璃效果的使用技巧和注意事项,需要的朋友参考一下 本文实例讲解了Android 虚化图片、模糊图片、图片毛玻璃效果的实现方法,具体内容如下 效果如图: 在Android可以用RenderScript方便的实现这个方法: 但是RenderScript的这个方法需要Android API17,也就说需要在An

  • 本文向大家介绍Android模糊处理简单实现毛玻璃效果,包括了Android模糊处理简单实现毛玻璃效果的使用技巧和注意事项,需要的朋友参考一下 自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果、磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片: 实现效果大家都知道了,如何在Android中实现呢,说白了就是对图片进行模糊化处理,小编先给大家讲一下