为所有行调用 heightForRowAtIndexPath在出现性能问题之前 UITableView 有多少行?

发布于 2024-10-22 21:54:55 字数 595 浏览 4 评论 0原文

我想我已经读到,对于 UITableView 来说,heightForRowAtIndexPath 不会在所有行上调用,而只会在可见的行上调用。但这不是我所看到的。例如,我看到数百个对 heightForRowAtIndexPath 的调用,用于更改 iPhone 方向的简单情况。

因此,我在这里假设,对于实现了 heightForRowAtIndexPathUITableView ,它确实(即 heightForRowAtIndexPath)被所有行调用(不仅仅是可见的)...如果这不太正确,请告诉我。

问题:鉴于上述情况,在通常出现性能问题之前,UITableView(其中实现 heightForRowAtIndexPath)可以有多少行?

解决性能问题的方法?即为每行设置一个标称/标准高度,而不实现 heightForRowAtIndexPath,但只有在显示时正确设置每行高度并在此处正确设置...但是哪种方法可以在其中执行此操作?

I thought I had read that for a UITableView that heightForRowAtIndexPath doesn't get called on all rows, but only on the ones that will be visible. This isn't what I'm seeing however. I'm seeing hundreds of calls to heightForRowAtIndexPath for the simple situation of the orientation being changed of the iPhone for example.

So I'm assuming here therefore that for a UITableView with heightForRowAtIndexPath implemented, it does (i.e. heightForRowAtIndexPath) get called for all rows (not just the visible ones)...let me know if this isn't quite correct.

QUESTION: Given the above, how many rows in a UITableView (where heightForRowAtIndexPath is implemented) can you have before performance issues occur typically?

Is there a way around the performance issues? i.e. set a nominal/standard height for each row and not implement heightForRowAtIndexPath, but then correctly set each row height only when it is displayed and set it correctly here...but which method would one do this in?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

当梦初醒 2024-10-29 21:54:55

查看 tableView:heightForRowAtIndexPath: 文档

该方法允许委托指定具有不同高度的行。如果实现此方法,它返回的值将覆盖为给定行的 UITableView 的 rowHeight 属性指定的值。

使用 tableView:heightForRowAtIndexPath: 而不是 rowHeight 属性会对性能产生影响。每次显示表视图时,它都会在委托上为其每一行调用 tableView:heightForRowAtIndexPath: ,这可能会导致具有大量行(大约 1000 或更多)的表视图出现严重的性能问题。

因此,您应该使用 UITableView 的 rowHeight 属性。如果您需要不同的高度,那么您就不走运了,因为您必须使用 tableView:heightForRowAtIndexPath:

AFAIK 无法更改显示时的行高。
表格视图之前必须知道正确的大小,否则会一直出现难看的位置移动。

Have a look at the discussion section in the tableView:heightForRowAtIndexPath: documentation

The method allows the delegate to specify rows with varying heights. If this method is implemented, the value it returns overrides the value specified for the rowHeight property of UITableView for the given row.

There are performance implications to using tableView:heightForRowAtIndexPath: instead of the rowHeight property. Every time a table view is displayed, it calls tableView:heightForRowAtIndexPath: on the delegate for each of its rows, which can result in a significant performance problem with table views having a large number of rows (approximately 1000 or more).

So you should use the rowHeight property of the UITableView. If you need different heights you are out of luck because you have to use tableView:heightForRowAtIndexPath:.

AFAIK there is no way to change the row height at display.
The tableview has to know the correct size before, otherewise there would be ugly position shifts all the time.

扎心 2024-10-29 21:54:55

我想我找到了解决方案。

在 iOS 7 中,苹果引入了一些新的 tableview 属性。其中之一是:

tableView:estimatedHeightForRowAtIndexPath:

例如,如果您提供估计的行高,那么当在显示表格之前重复调用 tableView:heightForRowAtIndexPath: 时,仅针对表格的可见单元格调用它;对于剩余的单元格,使用估计的高度。

以下是该信息的来源:https://books.google.gr/books?id=wLaVBQAAQBAJ&pg=PT521&lpg=PT521&dq=heightforrowatindexpath+only+for+the+visible+cells&source=bl&ots=7tuwaMT5zV&sig =h3q8AaFvoCgcrPu2fQchVkIEjwg&hl=en&sa=X&ved=0CEMQ6AEwBWoVChMInLK0xbPuxwIVCbUaCh3_nQWG#v=onepage&q=heightforrowatindexpath%20only%20for%20the%20visible%20cells&f=false

I think I found a solution to that.

In iOS 7 apple introduced some new tableview properties. One of them is the:

tableView:estimatedHeightForRowAtIndexPath:

So if you supply an estimated row height, for example, then when tableView:heightForRowAtIndexPath: is called repeatedly before the table is displayed, it is called only for the visible cells of the table; for the remaining cells, the estimated height is used.

Here is the source for that information: https://books.google.gr/books?id=wLaVBQAAQBAJ&pg=PT521&lpg=PT521&dq=heightforrowatindexpath+only+for+the+visible+cells&source=bl&ots=7tuwaMT5zV&sig=h3q8AaFvoCgcrPu2fQchVkIEjwg&hl=en&sa=X&ved=0CEMQ6AEwBWoVChMInLK0xbPuxwIVCbUaCh3_nQWG#v=onepage&q=heightforrowatindexpath%20only%20for%20the%20visible%20cells&f=false

儭儭莪哋寶赑 2024-10-29 21:54:55

天哪,我花了一个多小时试图找到性能问题的根源!

最后我还发现了数百个对 heightForRowAtIndexPath 的调用和搜索
给我这个线程。这真的很烦人。
仅显示 250 个项目时,性能就已经下降。值得庆幸的是,我现在想要显示的单元格都具有相同的大小。但我可以想象有人想要为 tableView 显示一些不同的单元格 > 200 件商品!

修复这个苹果!

干杯

My goodness, I spent over an hour trying to find the source of my performance problem!

Finally I also found hundreds of calls to heightForRowAtIndexPath and a search
got me this thread. THAT is really annoying.
Performance goes down here already when just displaying 250 items. Thankfully the cells I want to display now all have the same size. But I could imagine someone wanting to display some different cells for a tableView with > 200 items!

FIX THIS APPLE!

Cheers

兔小萌 2024-10-29 21:54:55

提高具有大量行和动态单元格高度的 tableView 性能的一种方法是在首次计算单元格高度后缓存它们。

实现此目的的一个简单方法是保留一个 NSMutableDictionary,其中键是单元格中记录的 id(或您可能拥有的任何其他标识符),值是 NSNumber 与行的高度。首次计算出高度后,通过记录 id 将其存储到 NSMutableDictionary 中。在 tableView:heightForRowAtIndexPathtableView:estimatedHeightForRowAtIndexPath: 中,您检查字典中缓存的高度,如果找到则返回它。如果没有找到,则计算高度,并存储在缓存中,然后返回高度。

您可能必须小心使更改高度的行的缓存无效。例如,如果您的某个单元格中有一个展开按钮,则在点击展开按钮后调用高度的委托方法时,您将需要从缓存中删除该单元格的高度。

如果您尝试在表格显示时一次显示 1000 个单元格,则性能可能仍然会受到影响,因为它可能会调用每行的 height 方法。解决这个问题的方法是,在首次显示单元格之前,如果可能的话,在后台任务中首先预热缓存。

A way to improve performance in tableViews with a big number of rows and dynamic cell heights is to cache the height of the cells once they are first calculated.

A simplistic approach to achieve this is to keep a NSMutableDictionary in which the key is the id of the record in the cell (or any other identifier you might have), and the value is a NSNumber with the height of the row. Once the height is first calculated, store it the NSMutableDictionary by the record id. In the tableView:heightForRowAtIndexPath and tableView:estimatedHeightForRowAtIndexPath: you check for a cached height in the dictionary and return it if found. If not found, calculate the height, and store in the cache before returning the height.

You might have to be careful with invalidating the cache for the rows that change heights. For example, if you have an expand button in one of your cells, you will need to remove the height of that cell from cache once the expand button is tapped delegate method for height is called.

You might still have a performance hit if you try to display 1000 of cells at once when the table shows, as it will likely call the height method for each row. A work around for that is to first warm the cache, if possible in a background task, before first displaying the cells.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文