繁体   English   中英

如何提高混合性能以平滑滚动?

[英]How to improve blending performance to make smooth scrolling?

快速介绍

编辑:我有9个单元格。 所有9个单元格都包含捆绑图像。 7个捆绑包图像具有某种透明度( 在文件中,而不是代码中的混合选项 ),可以从下面的Web加载图像。 当捆绑包和Web图像都作为UIImage对象加载到数组中时,滚动问题会影响表视图。

如果我禁用网络图像的绘制,滚动效果很好,但是当我从捆绑滚动中禁用图像时,效果还不错。 但是在一起,您会得到自己不想要的东西:糟糕的用户体验。

履行

我在女巫中使用模型,您有一个自定义UITableViewCell ,其中一个自定义UIView设置为Cell的backgroundView

自定义UIView包含两个单元大小的图像( 320x80 px )。 所有元素均设置为不透明并具有1.0 Alpha属性,但是其中一个图像部分是100%透明的。

我不重复使用单元,因为我无法使它们加载不同的图像。 Cell可以一一重用,最多可重复使用9个电池。 所以我在内存中有9个可重复使用的单元。 也许这就是问题所在。

单元格initWithStyle:reuseIdentifier方法部分:

CGRect viewFrame = CGRectMake(0.0f, 0.0f, 320.0f, 80.0f);
customCellView = [[CustomCellView alloc] initWithFrame:viewFrame];
customCellView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self setBackgroundView:customCellView];

CustomCellView的初始化方法:

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.opaque = YES;
        self.backgroundColor = [UIColor UICustomColor];
    }
    return self;
}

使用UIImage的 imageWithData:方法(异步下载 ),将图像作为PNG Web定位文件( 40-80 imageWithData: )中的UIImage对象作为UIImage对象加载到NSMutableArray中。

在图像加载方法中将它们设置为可见单元,并从数组中将其设置为保存到 UITableViewDelegate的方法tableView:cellForRowAtIndexPath: ,并通过UITableViewCell和自定义方法传递给UIView。

然后在UIView的drawRect:绘制drawRect:重写的方法:

- (void)drawRect:(CGRect)rect {
    CGRect contentRect = self.bounds; 
    if (!self.editing) {
        CGFloat boundsX = contentRect.origin.x;
        CGFloat boundsY = contentRect.origin.y;
        CGPoint point;
        point = CGPointMake(boundsX, boundsY);
        if (firstImage)  { [firstImage  drawInRect:contentRect blendMode:kCGBlendModeNormal alpha:1.0f]; }
        if (secondImage) { [secondImage drawInRect:contentRect blendMode:kCGBlendModeNormal alpha:1.0f]; }
    }
}

如您所见,正在使用drawInRect:blendMode:alpha:方法绘制图像。

问题

好吧,当在设备上滚动UITableView 时,您会在滚动期间每次加载新单元时注意到停机时间( 对用户不利,非常糟糕 )。

编辑:问题更多是混合问题,在代码中您看到互联网图像被绘制在已捆绑的图像下面-不绘制重叠图像使滚动速度提高了70%。

思考

从捆绑包加载图像时,相同的实现没有停机时间。 我应该将图像保存到应用程序沙箱,然后从那里使用它们。 这听起来非常糟糕,因为您应该尽量减少移动设备应用程序中的读写操作,因为每次读取或写入磁盘时都会快要死掉。

编辑:或者也许我应该将图像存储为核心图形对象?

编辑: 这个问题有一些线索。 但是我不知道如何有效地执行自定义绘图。

首先,您应该尝试使表单元可重用。.这将对内存使用和响应能力产生重大影响。

为了从tableView中的Web加载图像,我使用了此链接文本解决方案。 它使用ASIHTTPRequest框架来异步下载数据,并且具有自定义的可重用单元。

您可以按原样使用它,也可以根据需要对其进行调整...您可以在显示tableView之前异步下载所有图像,并将其保存在缓存中。 使用上面链接中建议的代码从缓存而非网络加载图像。 如果这样做,您可能会下载比用户所需更多的数据(如果某人使用3G且流量有限,他将不喜欢额外的流量...)

更好的解决方案是仅在需要时才下载图像。 您可以按原样使用代码并添加一个缓存模块。 下载图像后,例如将其保存在字典中,下次请求从那里加载时...

每当我需要在UITableView单元中加载图像时,最后一种方法就足够了。 无需将图像另存为Core Graphics对象。

希望能帮助到你...

编辑:在tableview中加载具有可重复使用单元格的图像的另一种解决方案

来自http://iphoneincubator.com/blog/tag/uiimage

像这样将两个图像组合在一起。 只有9行,您应该在任何地方都没有延迟。

- (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage *)image2 {  
UIGraphicsBeginImageContext(image1.size);  

// Draw image1  
[image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];  

// Draw image2  
[image2 drawInRect:CGRectMake(0, 0, image2.size.width, image2.size.height)];  

UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();  

UIGraphicsEndImageContext();  

return resultingImage;  
}  

尝试构建一个图像缓存,它是一个新的obj-c对象,该对象仅返回您需要的UIImage,最多保留最后50个左右的UIImages。 然后该单元开始绘制,它只是向缓存对象询问图像-要么立即获取它,要么缓存对象开始下载它。

UImage* theImage = [myImageCache imageForURL:urlForPNGImage]; 
[theImage drawinRect:rectForImageInCell];

// imageCache具有UIImages字典,其中图像以URL作为键存储。 您还需要跟踪诸如上次使用的时间等内容,以便可以控制内存。

另外,无论使用什么图像缓存,都需要为用户尚未看到的行加载图像。 只需在显示的行的两侧提前加载10(或其他一些数字)即可。 然后图像准备就绪。 即致电

for (rows unseenButNearTheView)
 urlForRow = blah
 [myImageCache imageForURL:urlForRow]; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM