我创建了一个遵循
我设置了表格的
为了在单元格之间有自定义间距,我使行高比想要的高,并定制了单元格的contentView的大小,使其看起来像是有额外的空间(参考这个SO答案)。
我想给单元格添加模糊效果,以使背景变得模糊。我使用了 Brad Larson的GPUImage框架 来实现这个目的。这个方法能正常工作,但由于我希望随着滚动更新背景模糊效果,因此滚动变得非常卡顿。
我的代码如下:
现在来谈谈问题:
有没有更好的方法添加模糊效果?也许可以使图层不必每次移动都重新渲染吗?iOS7的控制中心/通知中心似乎能够做到这一点而没有任何延迟。
UITableViewDataSource
和UITableViewDelegate
协议的UIViewController
,并将UITableView
设置为它的子视图。我设置了表格的
backgroundView
属性为UIImageView
,以便将图片显示为表格的背景。为了在单元格之间有自定义间距,我使行高比想要的高,并定制了单元格的contentView的大小,使其看起来像是有额外的空间(参考这个SO答案)。
我想给单元格添加模糊效果,以使背景变得模糊。我使用了 Brad Larson的GPUImage框架 来实现这个目的。这个方法能正常工作,但由于我希望随着滚动更新背景模糊效果,因此滚动变得非常卡顿。
我的代码如下:
//Gets called from the -scrollViewDidScroll:(UIScrollView *)scrollView method
- (void)updateViewBG
{
UIImage *superviewImage = [self snapshotOfSuperview:self.tableView];
UIImage* newBG = [self applyTint:self.tintColour image:[filter imageByFilteringImage:superviewImage]];
self.layer.contents = (id)newBG.CGImage;
self.layer.contentsScale = newBG.scale;
}
//Code to create an image from the area behind the 'blurred cell'
- (UIImage *)snapshotOfSuperview:(UIView *)superview
{
CGFloat scale = 0.5;
if (([UIScreen mainScreen].scale > 1 || self.contentMode == UIViewContentModeScaleAspectFill)) {
CGFloat blockSize = 12.0f/5;
scale = blockSize/MAX(blockSize * 2, floor(self.blurRadius));
}
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -self.frame.origin.x, -self.frame.origin.y);
NSArray *hiddenViews = [self prepareSuperviewForSnapshot:superview];
[superview.layer renderInContext:context];
[self restoreSuperviewAfterSnapshot:hiddenViews];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
-(UIImage*)applyTint:(UIColor*)colour image:(UIImage*)inImage{
UIImage *newImage;
if (colour) {
UIGraphicsBeginImageContext(inImage.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, inImage.size.width, inImage.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSaveGState(ctx);
CGContextClipToMask(ctx, area, inImage.CGImage);
[[colour colorWithAlphaComponent:0.8] set];
CGContextFillRect(ctx, area);
CGContextRestoreGState(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeLighten);
CGContextDrawImage(ctx, area, inImage.CGImage);
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
} else {
newImage = inImage;
}
return newImage;
}
现在来谈谈问题:
有没有更好的方法添加模糊效果?也许可以使图层不必每次移动都重新渲染吗?iOS7的控制中心/通知中心似乎能够做到这一点而没有任何延迟。
也许可以使用GPUImageUIElement
类?如果是这样,我该如何使用呢?
我看过的另一种方法是最初在背景图像上创建模糊,然后仅裁剪我需要使用的区域,但是我无法使其正常工作,因为图像可能与屏幕大小相同或不同,因此缩放是一个问题(使用CGImageCreateWithImageInRect()
和rect是表格上单元格位置)。
我还发现必须将模糊添加到表视图本身,框架为单元格的框架,而单元格具有透明颜色。
提前致谢
编辑 根据请求,以下是我之前尝试过的图像裁剪代码:
- (void)updateViewBG
{
//self.bgImg is the pre-blurred image, -getContentViewFromCellFrame: is a convenience method to get just the content area from the whole cell (since the contentarea is smaller than the cell)
UIImage* bg = [self cropImage:self.bgImg
toRect:[LATableBlur getContentViewFromCellFrame:[self.tableView rectForRowAtIndexPath:self.cellIndexPath]]];
bg = [self applyTint:self.tintColour image:bg];
self.layer.contents = (id)bg.CGImage;
self.layer.contentsScale = bg.scale;
}
- (UIImage*)cropImage:(UIImage*)image toRect:(CGRect)frame
{
CGSize imgSize = [image size];
double heightRatio = imgSize.height/self.tableView.frame.size.height;
double widthRatio = imgSize.width/self.tableView.frame.size.width;
UIImage* cropped = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(image.CGImage,
CGRectMake(frame.origin.x*widthRatio,
frame.origin.y*heightRatio,
frame.size.width*widthRatio,
frame.size.height*heightRatio))];
return cropped;
}