- Introduce ASLayoutNode and its subclasses.
- ASDisplayNode measures its ASLayoutNode and cache the result (ASLayout). Calculated size and position of each subnode can be retrieved from the calculated layout.
- Custom nodes need to override -layoutNodeThatFits:(CGSize) instead of -calculateSizeThatFits:(CGSize).
- Custom nodes do not need to layout its subnodes (in -layout:) anymore. ASDisplayNode can handle the job most of the time, by walking through its layout tree.
- ASCompositeNode is used to embed (display) subnodes to a node's layout. That way, each subnode will also be measured while the parent node is measuring. And the parent node knows where its subnodes are within its layout.
This applies primarily when beginUpdates / endUpdates is not used.
Due to user interaction-driven edits, like reloads or adding content
at the bottom, sometimes this is unavoidable in app design and thus
critical.
I have a diff in flight to make ASDataController / ASRangeController
robust against very aggressive thrash testing, which will be added
both to the unit test suite and this new example project.
Most UITableViewCell properties aren't useful in conjunction with
ASCellNode -- the system's UIView properties are unsupported for
performance reasons, and properties that configure them (e.g., content
indentation) don't affect custom node hierarchies. This patch adds
support to _ASTableViewCell for the properties that *are* useful.
r=scottg
Introduce `ASTableView`, a UITableView subclass that uses `ASCellNode`
instead of UITableViewCell. Add working range support via
`ASRangeController`, which observes the visible range, maintains a
working range, and handles most ASDK machinery. ASRangeController is
loosely-enough coupled that it should be easily adapted to
UICollectionView if that's desired in the future.
Notable considerations in the ASRangeController architecture:
* There's no sense rewriting UITableView -- the real win comes from
using nodes instead of UITableViewCells (easily parallelisable
computation, large number of cells vs. few table views, etc.). So,
use a UITableView with empty cells, using UITableViewCell's
contentView as a host for arbitrary node hierarchies.
* Instead of lazy-loading cells the instant they're needed by
UITableView, load them in advance. Preload a substantial number of
nodes in the direction of scroll, as well as a small buffer in the
other direction.
* Maintain compatibility with UITableView's API, with one primary change
-- consumer code yields configured ASCellNodes, not UITableViewCells.
* Don't use -tableView:heightForRowAtIndexPath:. Nodes already compute
their preferred sizes and cache results for use at layout-time, so
ASTableView uses their calculatedSizes directly.
* Corollary: ASTableView is only aware of nodes that have been sized.
This means that, if a cell appears onscreen, it has layout data and
can display a "realistic placeholder", e.g. by making its subnodes'
background colour grey.
Other improvements:
* Remove dead references and update headers (fixes#7, #20).
* Rename `-[ASDisplayNode sizeToFit:]` to `-measure:` and fix
`constrainedSizeForCalulatedSize` typo (fixes#15).
* Rename `-willAppear` and `-didDisappear` to `-willEnterHierarchy` and
`-didExitHierarchy`. Remove `-willDisappear` -- it was redundant, and
there was no counterpart `-didAppear`.
* Rename `viewLoaded` to `nodeLoaded`.