首先来个演示动画镇楼!
步骤详解:
- 说下思路,很简单,首先自定义一个
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;
}