我制作了一个UIViewController
符合UITableViewDataSource
andUITableViewDelegate
协议的,并且有一个UITableView
作为它的子视图。
我已将backgroundView
表格的属性设置为 a UIImageView
,以便将图像显示为表格的背景。
为了在单元格之间有自定义间距,我使行高比我想要的大,并将单元格的 contentView 自定义为我想要的大小,使它看起来像有额外的空间(遵循这个 SO 答案)。
我想为单元格添加模糊效果,使背景模糊,我通过Brad Larson 的 GPUImage framework做到了这一点。但是,这很好用,因为我希望背景模糊在滚动时更新,所以滚动变得非常滞后。
我的代码是:
//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()
和矩形是表格上单元格的位置)。
我还发现我必须将模糊添加到 tableview 本身,框架是单元格的框架,并且单元格具有清晰的颜色。
提前致谢
编辑 根据要求,这是我之前尝试过的图像裁剪代码:
- (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;
}