简体   繁体   English

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

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

Fast intro 快速介绍

Edit: I have 9 cells. 编辑:我有9个单元格。 All 9 cells contain bundle image. 所有9个单元格都包含捆绑图像。 7 bundle images have some kind of transparency ( in file, not as a blending option in code ) to load images from web underneath them. 7个捆绑包图像具有某种透明度( 在文件中,而不是代码中的混合选项 ),可以从下面的Web加载图像。 The scrolling problem affects the table view when both bundle and web images are loaded into arrays as UIImage objects. 当捆绑包和Web图像都作为UIImage对象加载到数组中时,滚动问题会影响表视图。

If I disable drawing of web images scrolling is beautiful, when I disable image from bundle scrolling is pretty OK. 如果我禁用网络图像的绘制,滚动效果很好,但是当我从捆绑滚动中禁用图像时,效果还不错。 But together you get what you don't want to have: bad user experience. 但是在一起,您会得到自己不想要的东西:糟糕的用户体验。

Implementation 履行

I am using model in witch you have a custom UITableViewCell with one custom UIView set up as Cell's backgroundView . 我在女巫中使用模型,您有一个自定义UITableViewCell ,其中一个自定义UIView设置为Cell的backgroundView

Custom UIView contains two Cell-sized images ( 320x80 px ). 自定义UIView包含两个单元大小的图像( 320x80 px )。 All elements are set to be Opaque and have 1.0 Alpha property, but one of images is partially 100% transparent. 所有元素均设置为不透明并具有1.0 Alpha属性,但是其中一个图像部分是100%透明的。

I don't reuse Cells because I failed to make them loading different images. 我不重复使用单元,因为我无法使它们加载不同的图像。 Cell's reused one-by-one up to 9 cells overall. Cell可以一一重用,最多可重复使用9个电池。 So I have 9 reusable Cells in memory. 所以我在内存中有9个可重复使用的单元。 Maybe that's the issue. 也许这就是问题所在。

Cell initWithStyle:reuseIdentifier method part: 单元格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 's initialization method: CustomCellView的初始化方法:

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

Images are being loaded to NSMutableArray as UIImage objects from PNG web-located files ( 40 - 80 kBytes) with UIImage's imageWithData: method ( after asynchronous download). 使用UIImage的 imageWithData:方法(异步下载 ),将图像作为PNG Web定位文件( 40-80 imageWithData: )中的UIImage对象作为UIImage对象加载到NSMutableArray中。

They are being set in for visible cells in image-loading method and set from array they were saved to in UITableViewDelegate's method tableView:cellForRowAtIndexPath: and passed through UITableViewCell with custom method to UIView. 在图像加载方法中将它们设置为可见单元,并从数组中将其设置为保存到 UITableViewDelegate的方法tableView:cellForRowAtIndexPath: ,并通过UITableViewCell和自定义方法传递给UIView。

And then drawn in UIView's drawRect: overridden method: 然后在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]; }
    }
}

As you see images are being drawn with drawInRect:blendMode:alpha: method. 如您所见,正在使用drawInRect:blendMode:alpha:方法绘制图像。

Problem 问题

Well, when UITableView is being scrolled on the device you can notice ( noticing is bad for user, very bad ) downtime each time it loads new cell during scrolling. 好吧,当在设备上滚动UITableView 时,您会在滚动期间每次加载新单元时注意到停机时间( 对用户不利,非常糟糕 )。

Edit: Problem is more of blending problem, in code you see that the internet image is being drawn underneath the one already in bundle - not drawing the overlapping image made scrolling 70% faster. 编辑:问题更多是混合问题,在代码中您看到互联网图像被绘制在已捆绑的图像下面-不绘制重叠图像使滚动速度提高了70%。

Thoughts 思考

Same implementation have no downtime when loading images from bundle. 从捆绑包加载图像时,相同的实现没有停机时间。 Should I save images to Application Sandbox and then use them from there. 我应该将图像保存到应用程序沙箱,然后从那里使用它们。 It sounds very bad because you should minimize read-write operations in mobile device application, because disk is slowly dying each time you read or write. 这听起来非常糟糕,因为您应该尽量减少移动设备应用程序中的读写操作,因为每次读取或写入磁盘时都会快要死掉。

Edit: Or maybe I should store images as Core Graphics objects? 编辑:或者也许我应该将图像存储为核心图形对象?

Edit: There some clues in this question. 编辑: 这个问题有一些线索。 But I don't know how do do the custom drawing effectively. 但是我不知道如何有效地执行自定义绘图。

First you should try to make your table cells reusable..it will make a big difference for memory usage and responsiveness.. 首先,您应该尝试使表单元可重用。.这将对内存使用和响应能力产生重大影响。

For loading images from the web in a tableView i used this link text solution. 为了从tableView中的Web加载图像,我使用了此链接文本解决方案。 It uses the ASIHTTPRequest framework for downloading data async and it has custom reusable cells. 它使用ASIHTTPRequest框架来异步下载数据,并且具有自定义的可重用单元。

You could use it as it is or you can adapt it to your needs... You could download all your images async before you show the tableView and keep them in a cache. 您可以按原样使用它,也可以根据需要对其进行调整...您可以在显示tableView之前异步下载所有图像,并将其保存在缓存中。 Use the code proposed at the link above to load the images from the cache not from the web. 使用上面链接中建议的代码从缓存而非网络加载图像。 If you do it like this you may download more data than the user needs at one moment.(If someone is on 3G and it has limited traffic he wouldn't appreciate the extra trafic...) 如果这样做,您可能会下载比用户所需更多的数据(如果某人使用3G且流量有限,他将不喜欢额外的流量...)

A better solution would be to download the images only when they are needed. 更好的解决方案是仅在需要时才下载图像。 You could use the code as it is and add a cache module. 您可以按原样使用代码并添加一个缓存模块。 After the image is downloaded save it in dictionary for example and the next time it is requested load it from there... 下载图像后,例如将其保存在字典中,下次请求从那里加载时...

the last approach was enough every time i needed to load images in an UITableView cell. 每当我需要在UITableView单元中加载图像时,最后一种方法就足够了。 There was no need to save images as Core Graphics objects. 无需将图像另存为Core Graphics对象。

Hope it helps... 希望能帮助到你...

Edit: another solution for loading images with reusable cells in a tableview 编辑:在tableview中加载具有可重复使用单元格的图像的另一种解决方案

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

Something like this to combine two images. 像这样将两个图像组合在一起。 With only 9 rows you should have no delays anywhere. 只有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;  
}  

Try building an image cache that is a new obj - c object that simply returns the UIImage you need, keeping up to the last 50 or so requested UIImages on hand. 尝试构建一个图像缓存,它是一个新的obj-c对象,该对象仅返回您需要的UIImage,最多保留最后50个左右的UIImages。 Then the cell goes to draw it just asks the cache object for an image - and either gets it right away, or the cache object starts to download it. 然后该单元开始绘制,它只是向缓存对象询问图像-要么立即获取它,要么缓存对象开始下载它。

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

// imageCache has a dictionary of UIImages with the image stored with URL as the key. // imageCache具有UIImages字典,其中图像以URL作为键存储。 You also need to track stuff like last used time, etc so you can keep memory under control. 您还需要跟踪诸如上次使用的时间等内容,以便可以控制内存。

Also, with whatever image cache you use, you need to load the images for rows that have not yet been seen by the user. 另外,无论使用什么图像缓存,都需要为用户尚未看到的行加载图像。 Just load 10 ahead (or some other number) on both sides of the shown rows. 只需在显示的行的两侧提前加载10(或其他一些数字)即可。 Then the image is ready to go. 然后图像准备就绪。 ie call 即致电

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

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

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