facebookarchive / AsyncDisplayKit

Smooth asynchronous user interfaces for iOS apps.
http://asyncdisplaykit.org
Other
13.4k stars 2.2k forks source link

[ASTableView] Support node-based header & footers (similar to Supplementary Nodes) #361

Closed ryanfitz closed 8 years ago

ryanfitz commented 9 years ago

I have an ASTableView which initially has 25 sections (and more sections as more data gets loaded). When the tableview initially renders, every section header is also getting rendered. This causes two main issues. 1 - there is major slow down in the app because every header is getting initialized and then asked to size itself. 2 - Every header appears on the screen for a quick moment and then jumps offscreen.

I have a few workarounds in place, but it would be great to get proper header & footer support added to ASTableView

Here is a sample of output when the tableview initially loads

secretiverhyme commented 9 years ago

Thanks for the report! The working range system currently only supports cells, not general accessory views; adding support for header / footer / accessory nodes will take some work, but it's on our radar.

As a (rather inelegant, unfortunately) workaround, you can use cells as section headers and accessory views -- if you need header pinning behaviour, you can implement it in a custom UICollectionViewFlowLayout subclass.

habitatus commented 9 years ago

I'm experiencing the same issue. Any progress on this? @ryanfitz care to share your workarounds?

appleguy commented 9 years ago

@habitatus you're using an ASTableView, not an ASCollectionView — right? It would be moderately difficult, but entirely feasible to support header / footer nodes. Are you using headers primarily for the pin-to-top behavior (like in Address Book), or can you switch to cells as a workaround?

habitatus commented 9 years ago

@appleguy Yep, I'm using ASTableView. Pin-to-top behaviour is the main reason I'm using the section headers (one per post, so there are a lot of views being initialised and sized on table reload). I plan on spending some time on researching how cell nodes work under the hood, and trying to apply similar logic to header nodes. I didn't have enough free time to do it yet, unfortunately.

ryanfitz commented 9 years ago

@habitatus I do have a workaround for loading up header nodes using an ASTableView. Its a pretty simple workaround where in tableView:viewForHeaderInSection: I load an ASDisplayNode (the header node) on a background thread and then jump to the main thread and add the header node to a UITableViewHeaderFooterView.

My solution works well enough where scrolling over very large datasets and frame rates remain high and there is no slowdown while scrolling. However, I would strongly suggest you switch to a ASCollectionView. I've found using an ASTableView for this pin-to-top behavior is really not supported with the current implementation. I've run into a number of issues trying to use ASTableView this way and will have to switch to another solution before I can release my app to the store.

I spent a good bit of time reading over the code to better understand how tableviews and collectionviews are implemented, with the hopes of putting together a pull request to get ASTableView production ready when used in this pin-to-top behavior. @appleguy will have a much better handle on it, but it appeared to be a major undertaking to nail down and fix all the issues I've run into.

habitatus commented 9 years ago

@ryanfitz Thx for your suggestions. I managed to get ASTableView pretty much under control :) This header view issue is basically the only remaining one that needs solving. I'll look into the gist you posted, hopefully it helps. Thx.

ryanfitz commented 9 years ago

Quick update on this issue for anyone looking for help on using nodes as headers / footers. I have an improved version of my workaround which works much more closely to how ASTableView renders rows. I'm seeing greatly improved performance over my previous solution, with no dropped frames when scrolling quickly over large datasets.

My solution is pretty messy currently, but I'll clean it up and get a gist up soon to help anyone looking for this feature. Its not something that would be appropriate as a PR, but should give enough direction to help others add this to their app.

habitatus commented 9 years ago

@ryanfitz Cool. I still didn't get around to implementing this on my own, so your solution will be much appreciated. Thanks!

ryanfitz commented 9 years ago

@habitatus I finally got around to putting together an example project which renders sticky headers in a table view. The headers are ASDisplayNodes and rendered off the main thread.

appleguy commented 8 years ago

@ryanfitz at the moment if you need this in production, I might recommend using ASCollectionView and its support for supplementary nodes. They work out of the box with UICollectionViewFlowLayouts, and you can use the ...LayoutInspecting protocol to make any custom layout compatible with them.

appleguy commented 8 years ago

If you have time to modify / integrate what you've built with the framework in a PR, I'd be stoked to merge it!

ryanfitz commented 8 years ago

When I get some time I'll put together a pr. My current solution, which is working well in a production app, works completely outside asdk for managing header / footer nodes.

Also, I just quickly put together a quick demo of a custom UICollectionViewLayout to support pinned headers. It worked great and was very easy to implement. If I was building a new app today I would probably switch to using collection views for this functionality.

appleguy commented 8 years ago

@ryanfitz @habitatus @secretiverhyme - The community is planning an exciting long term road map for the project and getting organized around how to deliver these feature requests. We are moving to a new issue tracker with more sophisticated planning capabilities (check out www.realArtists.com and their new product: Ship!).

If you are interested in helping contribute to this component or any other, don’t hesitate to send me an email at AsyncDisplayKit@gmail.com. If you would like to contribute for a few weeks, I can also add you to our Ship bug tracker so that you can see what everyone is working on and actively coordinate with us.

As always, keep filing issues and submitting pull requests here on Github and we will only move things to the new tracker if they require long term coordination.