使用 QuartzCore 对 UITableViewCell 内的 UIImageView 进行圆角时,滚动体验缓慢

Posted

技术标签:

【中文标题】使用 QuartzCore 对 UITableViewCell 内的 UIImageView 进行圆角时,滚动体验缓慢【英文标题】:Sluggish scrolling experience when using QuartzCore to round corners on UIImageView's within a UITableViewCell 【发布时间】:2011-04-18 06:07:20 【问题描述】:

我使用QuartzCoreUITableView 的单元格中为UIImageView 添加圆角

这是我使用的代码:

fooImageView.layer.cornerRadius = 9.0;
fooImageView.layer.masksToBounds = YES;
fooImageView.layer.borderWidth = 1.0;

问题是当我添加这段代码时。表格单元格的移动速度显着减慢。我只是想知道在使用这种技术滚动表格视图单元格时是否还有其他替代方法可以使用户体验更快并提高性能?

我看到许多应用程序(大多数 Twitter 应用程序)在将圆角应用于其单元格内的图像时性能没有下降。只是想知道他们是如何克服“呆滞”的?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我会尝试做的第一件事是设置:

fooImageView.layer.shouldRasterize = YES;

这会将圆角效果渲染为位图。不久前,我在 UIScrollView 中对视图使用 CALayer 效果时遇到了一些类似的问题,此设置极大地提高了性能。

别忘了设置

fooImageView.layer.rasterizationScale = [[UIScreen mainScreen] scale];

防止像素化(设备分辨率错误的光栅化)。

【讨论】:

我也会试试这个。感谢您的帮助。 就我而言,它立即增加了 15 FPS!缺点是单元格内图像视图中的图像质量:( @Stuart 。是否有任何其他事情要做才能平滑滚动。我正在使用 tableviewcell 中充满图像的应用程序。【参考方案2】:

我使用了 3 种提高 UITableView 性能的主要技术:

    始终重复使用单元格,使用 带标识符的出列可重用单元格 创建新单元格时。这 防止操作系统的开销 创造和摧毁许多 快速滚动时的对象。

    折叠视图层次结构 细胞。而不是拥有很多 视图和子视图,创建自定义 查看并完成所有单元格绘图 绘制矩形。 Twitter之类的应用程序使用 这种方法用于超快速单元格绘制。

    确保您的图像不透明。为此,您可以确保所有图像资源都没有烘焙 Alpha 通道并将图层的 opaque 属性设置为 YES。

例子:

在 cellForRowAtIndexPath 中(表标识符字符串只是创建对相同类型的单元格的引用,可以是任何你喜欢的):

static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
// Create a new cell if necessary
if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SimpleTableIdentifier] autorelease];

查看以下链接以获取提高 UITableViews 性能的示例:http://developer.apple.com/library/ios/#samplecode/TableViewSuite/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40007318-Intro-DontLinkElementID_2

希望这会有所帮助,

戴夫

【讨论】:

感谢您的回答。你能提供关于 dequeuereusablecellwithidentifier 的例子吗?你也可以详细说明drawRect中的单元格绘图吗? @Fulvio 没问题,上面的帖子中编辑了一些示例。要跟踪不透明度性能问题,您可以在工具下运行代码并使用 CoreAnimation 工具。这会将单元格中表现不佳的区域涂成红色。干杯戴夫。 感谢代码示例。这正是我首先构造我的 cellForRowAtIndexPath 的方式。所以我在那里很好。我将查看您提供的示例代码并查看其他替代方案。【参考方案3】:

你可以做一些掩蔽。用一个从它上面切出一个圆角正方形的蒙版图像覆盖图像,它会像一个魅力一样工作。

还要确保使用reuseCellIdentifier,否则如果表格变得有点复杂,表格将会滞后。

【讨论】:

【参考方案4】:

简答:将单元格设置为不透明并自己绘制。

遵循 StuDave 和 Magic Bullet 的建议,另请参阅官方 Twitter 客户端作者的Fast Scrolling in Tweetie with UITableView 了解如何进行单元格绘图。这是一个简单明了的示例项目。

除了解决这个特定问题之外,您还应该阅读 Matt Gallagher 的 UITableView construction, drawing and management (revisited),以了解如何编写自定义表格控制器和单元格。这不仅可以提高代码的性能,还可以让您完成 Apple 标准类无法完成的事情。基本上,您将创建一个复制UITableViewController 的关键方法的UIViewController

【讨论】:

感谢您的链接。非常感谢。 链接已失效 :( 有什么方法可以检索它吗? web.archive.org/web/20100322222950/http://blog.atebits.com/2008/… github.com/enormego/ABTableViewCell【参考方案5】:

在我的情况下,它添加了无穷无尽的子视图,并且表格视图正如您所说的那样显着减慢。我在willDisplayCell 中添加了这个逻辑来解决这个问题:

if cell.contentView.subviews.count < 3 /* elements in cell + subviews */   

        cell.contentView.addSubview(subView)
        cell.contentView.sendSubviewToBack(subView)

 

【讨论】:

以上是关于使用 QuartzCore 对 UITableViewCell 内的 UIImageView 进行圆角时,滚动体验缓慢的主要内容,如果未能解决你的问题,请参考以下文章

只使用Quartzcore / layer为UIView添加顶部边框?

为啥 UIView 不需要 QuartzCore.framework 工作?

QuartzCore 的 CALayer 问题

在 iOS 应用程序中使用 CoreAnimation / QuartzCore 动画 UILabel

在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息

未找到 QuartzCore/CAMetalLayer.h 文件