有效地继承 UIView

Posted

技术标签:

【中文标题】有效地继承 UIView【英文标题】:Subclassing an UIView efficiently 【发布时间】:2011-10-23 16:23:25 【问题描述】:

伙计们,我在继承 UIView 时遇到了一些麻烦。 我正在创建一个 IconView。 只是它是一些其他子视图的容器。 在我的 IconView 我有这个 iVar: UIImageView _background UIImageView _icon UILabel _iconLabel.

当我初始化 IconView 时,我用图像、文本和一些石英效果(如圆角和阴影)设置了这 3 个 iVar,然后我将它们添加到自身视图中。 一切都很好,但是如果我在一个空的滚动视图中插入一些这个 IconView(即 10),滚动效果就不流畅了。我在滚动视图中插入数千个简单的 UIView 之前尝试过,滚动动画效果很好。 我的 IconView 只有 10 个,滚动动画效果非常糟糕。

我可以采用不同的方式保留 UIImages 而不是 UIImageViews 并将其绘制在 drawRect: 方法中,但在这种情况下,我将失去 Autoresizing 属性和 Quartz 效果。

有什么建议吗? 谢谢,加布里埃尔。

【问题讨论】:

【参考方案1】:

不幸的是,UIScrollView 变得非常慢。有很多关于这个主题的帖子和文章,比如this Question和this (defect) blogpost以及it's sample code。在 2010 年的 WWDC 视频中也有关于“ios 中的性能优化”的三个会议,我强烈建议您观看。总结结论:尽可能少地使用子视图,并特别注意避免透明。

好的,关于“ScrollViews 中的性能”的一般性讨论就这么多,现在来谈谈您的情况:遇到同样的问题,我使用了上面文章和视频中的所有技巧,虽然它们提高了性能,但事实并非如此足够。我和你一样,在一些图像中使用了圆角,我发现这绝对会影响性能。只是停用它们比其他任何事情都更有帮助。阴影效果大概也是这样。

现在,您很可能希望保留这些圆角。我建议您创建图像的副本(或如果可能,请获取原件),然后使用those awesome classes 直接操作它们。这样,效果只会应用一次。它非常适合我。对于您的阴影,您可能只需在 Photoshop 中创建一些并在新的 ImageView 中使用它们。

如果这还不够,你应该尝试缓存你的IconViews,如果你还没有缓存TableViewCells

【讨论】:

我试图移除所有的 Quartz 效果,它帮助很大。谢谢,但是,意味着石英是相当不可用的?我应该只将它用于静态渲染吗?我不这么认为...我会阅读所有文章并观看视频以提高性能。 Quartz 在滚动视图中表现不佳。如果停用它可以解决您的问题,那么视频和文章不会,至少不会那么好。如果 shouldRasterize 没有帮助,您真的应该按照我的建议进行直接操作。 我开始阅读 WWDC 10 关于性能优化的讲座,但我需要找时间观看视频。在这一刻,我禁用了所有 Quartz 效果,并用建议的类别圆角。惊人的!!现在,带有数百个 IconView 的滚动非常快,但千个开始缓慢,但在我的情况下,我需要在滚动中使用 15 或 20 个。目前的结论是,正如你所说,不要在滚动中使用 Quartz :)【参考方案2】:

问题可能是石英阴影。如果大量使用它们真的会减慢渲染速度。

在您注销它们之前,您可以尝试将 CALayer 的 shouldRasterize 属性设置为 YES。这使得石英只渲染一次阴影并将其存储在缓冲区中。看看进展如何。

【讨论】:

您还应该将rasterizationScale 设置为屏幕比例。它可以通过[[UIScreen mainScreen] scale] 访问,但我相信API 差异存在一些复杂性......请参阅***.com/questions/3130420/… 应该在帮助中进行栅格化,它在我提到的视频之一中进行了介绍。如果您的单元格中不需要任何动画,您可以试一试。 @joerick 有帮助。现在动画很好,但不流畅。

以上是关于有效地继承 UIView的主要内容,如果未能解决你的问题,请参考以下文章

您如何有效地为数据库中的继承建模?

具有 UIView 继承类的 UIViewController,以编程方式

从 Kotlin Native 继承 UIView

当我继承 UIView 时,为啥我不能在图像上绘图?

如何初始化从 xib 加载的 UIView 子类?继承问题

从xib初始化的UIView如何继承?