【问题标题】:How to improve blending performance to make smooth scrolling?如何提高混合性能以实现平滑滚动?
【发布时间】:2010-09-04 19:09:16
【问题描述】:

快速介绍

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

如果我禁用 Web 图像的绘制,滚动是很漂亮的,当我禁用捆绑滚动的图像时,就很好了。但是在一起你会得到你不想拥有的东西:糟糕的用户体验。

实施

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

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

我不重复使用 Cell,因为我没能让它们加载不同的图像。 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;
}

图像被加载到 NSMutableArray 作为来自 PNG 网络定位文件 (40 - 80 kBytes) 的 UIImage 对象,UIImage's imageWithData:方法(异步下载)。

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

然后在UIView的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%。

想法

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

编辑:或者我应该将图像存储为 Core Graphics 对象?

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

【问题讨论】:

标签: iphone web-services performance uitableview uiimage


【解决方案1】:

来自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;  
}  

【讨论】:

    【解决方案2】:

    首先你应该尝试让你的表格单元格可重用..这将对内存使用和响应能力产生很大影响..

    为了在 tableView 中加载来自网络的图像,我使用了这个link text 解决方案。它使用 ASIHTTPRequest 框架来异步下载数据,并且具有自定义的可重用单元。

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

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

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

    希望对你有帮助...

    编辑: another solution 用于在表格视图中加载带有可重用单元格的图像

    【讨论】:

    • 我也可以使用谷歌。我的内存中有图像,如下所述:“图像被加载到 NSMutableArray 作为 UIImage 对象,来自 PNG 网络定位的文件,使用 UIImage 的 imageWithData: 方法(在异步下载之后)。”您链接的第一个示例是我的应用程序架构中的一个基础示例。但是图像有 64x64 像素的缩略图,并且存储方式与我的图像存储方式相同。第二个例子几乎相同,并且与问题无关。
    • 也许我不够明确..尝试解决可重复使用的单元格问题。还有你为什么使用 uiview 来显示图像,为什么不使用 uiimageview?我无意向您展示我知道如何使用谷歌而您不知道。我的链接的重点是为您提供一个 uitableview 示例,该示例使用异步下载和可重用单元从网络加载图像。 ..如果您已经使用该示例,也许您应该考虑为什么他们的图像加载正常并且表格滚动正常,但您的却没有..
    • 他们的图片加载速度很快,因为它们很小。 (大小和字节重)我只需要足够快地绘制图像,在[UIImage drawInRect:]中解码UIImage就是速度的泄漏。
    【解决方案3】:

    尝试构建一个图像缓存,它是一个新的 obj - c 对象,它只返回您需要的 UIImage,保持手头上最近 50 个左右请求的 UIImage。然后单元格开始绘制它只是向缓存对象询问图像 - 然后立即获取它,或者缓存对象开始下载它。

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

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

    此外,无论您使用何种图像缓存,您都需要为用户尚未看到的行加载图像。只需在所示行的两侧提前加载 10 个(或其他数字)。然后图像就准备好了。 即调用

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

    【讨论】:

    • 我有 9 个单元格。所有 9 个单元格都包含捆绑图像。 7 个捆绑图像具有某种透明度(在文件中,而不是作为代码中的混合选项)以从它们下面的网络加载图像。当捆绑图像和 Web 图像作为“UIImage”对象加载到数组中时,滚动问题会影响表格视图。如果我禁用 Web 图像的绘制滚动很漂亮,当我禁用捆绑滚动的图像时就很好了。但是在一起你会得到你不想拥有的东西:糟糕的用户体验。无论如何都很好,谢谢,但我没有 50 个单元格,并且没有单元格中要加载的图像。
    • 我明白了——解决这个问题的唯一方法是
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    相关资源
    最近更新 更多