ios – UITableViewCell contentView背景的快速模糊

ios – UITableViewCell contentView背景的快速模糊,第1张

概述我已经制作了一个符合UITableViewDataSource和UITableViewDelegate协议的UIViewController,并且有一个UITableView作为它的子视图. 我已将表的backgroundView属性设置为UIImageView,以便将图像显示为表格的背景. 为了在单元格之间有自定义间距我使行高比我想要的大,并将单元格的contentView自定义为我想要的大小, 我已经制作了一个符合UItableVIEwDataSource和UItableVIEwDelegate协议的UIVIEwController,并且有一个UItableVIEw作为它的子视图.

我已将表的backgroundVIEw属性设置为UIImageVIEw,以便将图像显示为表格的背景.

为了在单元格之间有自定义间距我使行高比我想要的大,并将单元格的contentVIEw自定义为我想要的大小,使它看起来像有额外的空间(Following this SO answer).

我想为单元格添加一个模糊,以便背景模糊,我在Brad Larson’s 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,inImage.size.wIDth,inImage.size.height);        CGContextScaleCTM(ctx,1,-1);        CGContextTranslateCTM(ctx,-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,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;}
解决方法 我设法用一个解决方案来解决它,起初我认为它不会起作用.

生成几个模糊的图像肯定不是解决方案,因为它花费了很多.
我只使用了一个模糊的图像并将其缓存.

所以我将UItableVIEwCell子类化:

@interface BlurredCell : UItableVIEwCell@end

我实现了两个类方法来访问缓存的图像(模糊和正常的)

+(UIImage *)normalimage{    static dispatch_once_t oncetoken;    static UIImage *_normalimage;    dispatch_once(&oncetoken,^{        _normalimage = [UIImage imagenamed:@"bg.png"];    });    return _normalimage;}

我在UIImage上使用了REFrostedViewController的类别来生成模糊图像

+(UIImage *)blurredImage{    static dispatch_once_t oncetoken;    static UIImage *_blurredImage;    dispatch_once(&oncetoken,^{    _blurredImage = [[UIImage imagenamed:@"bg.png"] re_applyBlurWithRadius:BlurredCellBlurRadius                                                                 tintcolor:[UIcolorcolorWithWhite:1.0f                                                                                            Alpha:0.4f]                                                     saturationDeltaFactor:1.8f                                                                 maskImage:nil];    });    return _blurredImage;}

为了在单元格内部产生模糊帧的效果,但仍然看到两侧的非模糊图像,我习惯滚动视图.

一个是带有普通图像的图像视图,另一个是带有模糊图像的图像视图.我将内容大小设置为图像的大小,contentOffset将通过接口设置.

因此,表视图最终以每个单元格保存整个背景图像,但在特定偏移处裁剪它并仍然显示整个图像

@implementation BlurredCell- (ID)initWithStyle:(UItableVIEwCellStyle)style reuseIDentifIEr:(Nsstring *)reuseIDentifIEr{    self = [super initWithStyle:style reuseIDentifIEr:reuseIDentifIEr];    if (self) {        // Initialization code        [self.contentVIEw addSubvIEw:self.normalScrollVIEw];        [self.contentVIEw addSubvIEw:self.blurredScrollVIEw];    }    return self;}-(UIScrollVIEw *)normalScrollVIEw{    if (!_normalScrollVIEw) {        _normalScrollVIEw = [[UIScrollVIEw alloc] initWithFrame:self.bounds];        _normalScrollVIEw.autoresizingMask = UIVIEwautoresizingFlexibleWIDth | UIVIEwautoresizingFlexibleHeight;        _normalScrollVIEw.scrollEnabled = NO;        UIImageVIEw *imageVIEw =[[UIImageVIEw alloc] initWithFrame:[UIScreen mainScreen].bounds];        imageVIEw.contentMode = UIVIEwContentModeScaletoFill;        imageVIEw.image = [BlurredCell normalimage];        _normalScrollVIEw.contentSize = imageVIEw.frame.size;        [_normalScrollVIEw addSubvIEw:imageVIEw];    }    return _normalScrollVIEw;}-(UIScrollVIEw *)blurredScrollVIEw{    if (!_blurredScrollVIEw) {        _blurredScrollVIEw = [[UIScrollVIEw alloc] initWithFrame:CGRectMake(BlurredCellpadding,BlurredCellpadding,self.bounds.size.wIDth - 2.0f * BlurredCellpadding,self.bounds.size.height - 2.0f * BlurredCellpadding)];        _blurredScrollVIEw.autoresizingMask = UIVIEwautoresizingFlexibleWIDth | UIVIEwautoresizingFlexibleHeight;        _blurredScrollVIEw.scrollEnabled = NO;        _blurredScrollVIEw.contentOffset = CGPointMake(BlurredCellpadding,BlurredCellpadding);        UIImageVIEw *imageVIEw =[[UIImageVIEw alloc] initWithFrame:[UIScreen mainScreen].bounds];        imageVIEw.contentMode = UIVIEwContentModeScaletoFill;        imageVIEw.image = [BlurredCell blurredImage];        _blurredScrollVIEw.contentSize = imageVIEw.frame.size;        [_blurredScrollVIEw addSubvIEw:imageVIEw];    }    return _blurredScrollVIEw;}-(voID)setBlurredContentOffset:(CGfloat)offset{    self.normalScrollVIEw.contentOffset = CGPointMake(self.normalScrollVIEw.contentOffset.x,offset);    self.blurredScrollVIEw.contentOffset = CGPointMake(self.blurredScrollVIEw.contentOffset.x,offset + BlurredCellpadding);}@end

setBlurredContentOffset:每次表视图的内容偏移量发生变化时都应该调用.

所以在表视图中委托的实现(视图控制器)我们在这两种方法中做到了:

// For the first rows-(voID)tableVIEw:(UItableVIEw *)tableVIEw willdisplayCell:(BlurredCell *)cell                                         forRowAtIndexPath:(NSIndexPath *)indexPath{    [cell setBlurredContentOffset:cell.frame.origin.y];}// Each time the table vIEw is scrolled-(voID)scrollVIEwDIDScroll:(UIScrollVIEw *)scrollVIEw{    for (BlurredCell *cell in [self.tableVIEw visibleCells]) {        [cell setBlurredContentOffset:cell.frame.origin.y - scrollVIEw.contentOffset.y];    }}

这是complete working demo

总结

以上是内存溢出为你收集整理的ios – UITableViewCell contentView背景的快速模糊全部内容,希望文章能够帮你解决ios – UITableViewCell contentView背景的快速模糊所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1065280.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存