简体   繁体   English

糟糕的UITableView滚动性能问题iOS 7

[英]Poor UITableView Scrolling Performance issue iOS 7

I have a UITableView that contains more than 20 rows, each UITableViewCell contains a UITextView which I can set different UIFont, alignment and colour. 我有一个包含超过20行的UITableView,每个UITableViewCell包含一个UITextView,我可以设置不同的UIFont,对齐和颜色。 When I scroll down or up there is a choppy or lagging during the scrolling, when I remove the font and text colours and alignment everything become perfect. 当我向下或向上滚动时,滚动过程中会出现波动或滞后,当我删除字体和文本颜色并对齐时,一切都变得完美。 Did Apple changes the way of redrawing text in iOS 7? Apple是否改变了在iOS 7中重绘文本的方式? This did not happen with the previous iOS versions. 以前的iOS版本没有发生这种情况。

instruments shows that the time consumed at dequeueReusableCellWithIdentifier:forIndexPath: 仪器显示dequeueReusableCellWithIdentifier:forIndexPath:消耗的时间dequeueReusableCellWithIdentifier:forIndexPath:

-- UPDATE Add Code - 更新添加代码

if (unit.fontName != nil ) {
            textView.font = [UIFont fontWithName:unit.fontName size:unit.fontSize.floatValue];
        }
        if (unit.fontColor) {
            textView.textColor=[self convertString:unit.fontColor];
        }
        else {
            textView.textColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:1];
        }
        if ([unit.fontSize floatValue] !=0) {
            textView.font = [UIFont fontWithName:textView.font.fontName size:[unit.fontSize floatValue]];
        }
        if (unit.textAlignment) {

            switch ([summaryUnit.textAlignment intValue]) {
                case 0:
                    textView.textAlignment = NSTextAlignmentLeft;
                    break;

                case 1:
                    textView.textAlignment = NSTextAlignmentCenter;
                    break;

                case 2:
                    textView.textAlignment = NSTextAlignmentRight;
                    break;

                default:
                    break;
            }

        }

There are a lot of things going on behind the scenes in an UITableView, that might not make it obvious why it appears unresponsive. 在UITableView中幕后发生了很多事情,这可能并不能说明为什么它看起来没有反应。

As an example, you should not do tons of work in the tableView:heightForRowAtIndexPath: as the UITableView needs to ask for the height of every single row in your dataset, regardless of whether they are apparent on the screen or not. 例如,你不应该在tableView:heightForRowAtIndexPath:做大量工作tableView:heightForRowAtIndexPath:因为UITableView需要询问数据集中每一行的高度,无论它们是否在屏幕上显而易见。 It does this in order to determine the content size. 它这样做是为了确定内容大小。

It might not at all be your data or your cells that causes the problem. 它可能根本不是您的数据或您的单元格导致问题。 Complex cells with lots of subviews might render slow in the compositor. 具有大量子视图的复杂单元格可能会在合成器中变慢。 Especially if you have things like transparency. 特别是如果你有透明度之类的东西。

Therefore I always put four basic rules down for myself whenever I am implementing a UITableView. 因此,每当我实现UITableView时,我总是为自己制定四个基本规则。

1) Always know what you need to tell the table view when you reload the data. 1)重新加载数据时,始终知道告诉表视图需要什么。 Don't do lot's of stuff in the data source or delegate methods. 不要在数据源或委托方法中做很多事情。 Have things ready for when UITableView needs it. 在UITableView需要它时准备好了。

2) Don't destroy and create views in the scroll cycle. 2)不要在滚动周期中销毁和创建视图。 By that, you should not create new UIView (or whatever) - as an example in your prepareForReuse methods. 因此,您不应该在prepareForReuse方法中创建新的UIView(或其他) - 作为示例。 Just reset content of existing views and controls, and then reconfigure them whenever UITableView asks you to. 只需重置现有视图和控件的内容,然后在UITableView要求时重新配置它们。

3) Don't have complex view hierarchies in your cells. 3)单元格中没有复杂的视图层次结构。 Especially transparency and out-of-bounds content that needs to be rendered, can be cumbersome for the compositor to render at fast enough speeds. 尤其是需要渲染的透明度和越界内容,对于合成器以足够快的速度渲染来说可能是麻烦的。

4) Don't configure your cells in tableView:cellForRowAtIndexPath: . 4)不要在tableView:cellForRowAtIndexPath:配置单元格tableView:cellForRowAtIndexPath: . Just dequeue and return the cell needed. 只需出列并返回所需的单元格。 Always configure and setup your cells in the tableView:willDisplayCell:forRowAtIndexPath: delegate method. 始终在tableView:willDisplayCell:forRowAtIndexPath: delegate方法中配置和设置单元格。

That being said, there are some tricks that can help you. 话虽这么说,有一些技巧可以帮助你。 As I mentioned above, don't create and destroy views or controls in the cell's prepareForReuse method. 如上所述,不要在单元格的prepareForReuse方法中创建和销毁视图或控件。 Don't do heavyweight work at all. 根本不做重量级的工作。 Just reset your views and go on. 只需重置您的观点并继续。 Which it might sound like you're doing, since it is the dequeueReusableCellWithIdentifier:forIndexPath: that causes your troubles. 这可能听起来像你正在做的,因为它是dequeueReusableCellWithIdentifier:forIndexPath:导致你的麻烦。

Lastly if it is because of compositing (Instruments would show work in some Quartz-related methods) you could succeed by using the shouldRasterize and rasterizationScale of your cell's CALayer. 最后,如果是因为合成(仪器将在某些与Quartz相关的方法中显示工作),您可以通过使用单元格的CALayer的shouldRasterizerasterizationScale来成功。 This can sometimes speed up rendering of cells considerable. 这有时可以加快细胞的渲染速度。

Let me know if any of this stuff makes sense, and if it might have solved your problem. 让我知道这些东西是否有意义,如果它可能解决了你的问题。

EDIT: 编辑:

PS. PS。 Yes. 是。 Apple did change the text-rendering in iOS 7. But why are you using UITextView?!? Apple确实改变了iOS 7中的文本呈现。但是你为什么要使用UITextView?!? I don't know it that well, but I know it is much more heavyweight than UITextField or UILabel. 我不太了解它,但我知道它比UITextField或UILabel更重要。 Maybe you could consider using those instead. 也许你可以考虑使用它们。 UITextView is usually for editing something that resembles documents (like the Notes app). UITextView通常用于编辑类似文档的内容(如Notes应用程序)。 I really think this might be what is causing your troubles. 我真的认为这可能是导致你烦恼的原因。

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

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