When is heightforrowatindexpath called




















If the heights of your rows are different, then you will end up in the wrong position in the table after switching mode. An approach I have taken here is to use performSelector:withObject:afterDelay after I've reloaded the table to call a method that does the scroll adjusting.

You need to use the delay, to allow time for the tableView to collect the new heights and the new table cells. There may be a smarter way of doing this. I do some sums to make the scroll adjustment based on the difference between the origin. So, for e. This answer is now outdated. DOM Level 4 introduced MutationObserver, providing an effective replacement for the deprecated mutation events. See this answer to another question for a better solution than the one presented here.

Since mutation events were deprecated in , and you have no control over the inserted elements because they are added by someone else's code, your only option is to continuously check for them.

Unless you need real-time element observation, it should be enough. Events in modern DOM implementations have two phases, capturing and bubbling. The capturing phase is the first phase, flowing from the defaultView of the document to the event target, followed by the bubbling phase, flowing from the event target back to the defaultView.

To handle the capturing phase of an event, you need to set the third argument for addEventListener to true :. Sadly, as Wesley mentioned, the capturing phase of an event cannot be handled reliably, or at all, in older browsers. One possible solution is to handle the mouseup event instead, since event order for clicks is:.

Part of the reason is that it's almost always cheaper or can be cheaper if you code it right to calculate the height of a row than it is to build and populate a whole cell. Given that in many tables the height of every cell will be identical, it is often vastly cheaper. And another part of the reason is because iOS needs to know the size of the whole table: this allows it to create the scroll bars and set it up on a scroll view etc.

So, unless every cell height is the same, then when a UITableView is created and whenever you send it a reloadData message, the datasource is sent one heightForRowAtIndexPath message for each cell. So if your table has 30 cells, that message gets sent 30 times. Say only six of those 30 cells are visible on screen. Some people are sometimes puzzled about how to calculate a cell height without creating the views themselves. But usually this is easy to do. For example, if your row heights vary in size because they hold varying amounts of text, you can use one of the sizeWithFont: methods on the relevant string to do the calculations.

This is quicker than building a view and then measuring the result. Note, that if you change the height of a cell, you will need to either reload the whole table with reloadData - this will ask the delegate for every height, but only ask for visible cells OR selectively reload the rows where the size has changed which, last time I checked, also calls heightForRowAtIndexPath: on ever row but also does some scrolling work for good measure. 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. 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 or more.

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.

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. THAT is really annoying.

Performance goes down here already when just displaying items. Thankfully the cells I want to display now all have the same size. 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. 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 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.

The general intention is that this is a faster and light-on-memory method that can be called for every row in the table quite frequently. This contrasts with cellForRowAtIndexPath: which is often slower and more memory intensive, but is only called for the rows that are actually need to be displayed at any given time. Why do Apple implement it like this? Part of the reason is that it's almost always cheaper or can be cheaper if you code it right to calculate the height of a row than it is to build and populate a whole cell.

Given that in many tables the height of every cell will be identical, it is often vastly cheaper. And another part of the reason is because iOS needs to know the size of the whole table: this allows it to create the scroll bars and set it up on a scroll view etc. So, unless every cell height is the same, then when a UITableView is created and whenever you send it a reloadData message, the datasource is sent one heightForRowAtIndexPath message for each cell.

So if your table has 30 cells, that message gets sent 30 times. Say only six of those 30 cells are visible on screen. Some people are sometimes puzzled about how to calculate a cell height without creating the views themselves. But usually this is easy to do. For example, if your row heights vary in size because they hold varying amounts of text, you can use one of the sizeWithFont: methods on the relevant string to do the calculations. This is quicker than building a view and then measuring the result.

Note, that if you change the height of a cell, you will need to either reload the whole table with reloadData - this will ask the delegate for every height, but only ask for visible cells OR selectively reload the rows where the size has changed which, last time I checked, also calls heightForRowAtIndexPath: on ever row but also does some scrolling work for good measure.



0コメント

  • 1000 / 1000