mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-12 22:33:59 +08:00
Merge pull request #1610 from lappp9/gh-pages
[AsyncDisplayKit.org] General cleanup, styling and rewording
This commit is contained in:
@@ -7,4 +7,7 @@ next: text-cell-node.html
|
||||
|
||||
ASCellNode is maybe the most commonly <a href = "subclassing.html">subclassed node</a>. It can be used as the cell for both ASTableNodes and ASCollectionNodes.
|
||||
|
||||
If you don't feel like subclassing you're also free to use the `-initWithView:` or `initWithViewController:` methods to return nodes with backing views created from an existing view or view controller you already have.
|
||||
That being said, subclassing it is largely the same as subclassing a regular ASDisplayNode. Most importantly, you'll write an -init method, a -layoutSpecThatFits: method for measurement and layout, and, if necessary, a -didLoad method for adding extra gesture recognizers and a -layout method for any extra layout needs.
|
||||
|
||||
If you don't feel like subclassing you're also free to use the `-initWithView:` or `-initWithViewController:` methods to return nodes with backing views created from an existing view or view controller you already have.
|
||||
|
||||
|
||||
@@ -5,39 +5,77 @@ permalink: /docs/containers-ascollectionnode.html
|
||||
next: containers-aspagernode.html
|
||||
---
|
||||
|
||||
`ASCollectionNode` is equivalent to UIKit's `UICollectionView` and can be used in place of any UICollectionView.
|
||||
ASCollectionNode is equivalent to UIKit's UICollectionView and can be used in place of any UICollectionView.
|
||||
|
||||
ASCollectionNode replaces UICollectionView's required method
|
||||
|
||||
`collectionView:cellForItemAtIndexPath:`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle">
|
||||
<a data-lang="swift" class="swiftButton">Swift</a>
|
||||
<a data-lang="objective-c" class = "active objcButton">Objective-C</a>
|
||||
</span>
|
||||
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
|
||||
</pre>
|
||||
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
with your choice of **_one_** of the following methods
|
||||
|
||||
`- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
|
||||
or
|
||||
|
||||
`- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath` **_(recommended)_**
|
||||
|
||||
<div class = "note">
|
||||
Note that these are the same methods as the `ASTableNode`! Please read the previous <a href = "containers-astablenode.html">`ASTableNode`</a> section as most of the details here are identical and so we will gloss over them quickly.
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
</pre>
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func collectionView(collectionView: ASCollectionView, nodeForItemAtIndexPath indexPath: NSIndexPath) -> ASCellNode
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
As noted in the previous section
|
||||
<p>
|
||||
or
|
||||
</p>
|
||||
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
</pre>
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func collectionView(collectionView: ASCollectionView, nodeBlockForItemAtIndexPath indexPath: NSIndexPath) -> ASCellNodeBlock
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
It is recommended that you use the node block version of the method so that your collection node will be able to prepare and display all of its cells concurrently.
|
||||
|
||||
As noted in the previous section:
|
||||
|
||||
<ul>
|
||||
<li>both of these ASCollectionView methods should not implement reuse (they will be called once per row)</li>
|
||||
<li>`collectionView:nodeBlockForRowAtIndexPath:` is preferred to `collectionView:nodeForItemAtIndexPath:` for its concurrent processing</li>
|
||||
<li>it is very important that node blocks be thread-safe</li>
|
||||
<li>ASCellNodes are used by ASTableNode, ASCollectionNod and ASPagerNode</li>
|
||||
<li>ASCollectionNodes do not utilize cell resuse.</li>
|
||||
<li>Using the "nodeBlock" method is preferred.</li>
|
||||
<li>It is very important that the returned node blocks are thread-safe.</li>
|
||||
<li>ASCellNodes can be used by ASTableNode, ASCollectionNode and ASPagerNode.</li>
|
||||
</ul>
|
||||
|
||||
##Replace UICollectionViewController with ASViewController##
|
||||
### Replacing a UICollectionViewController with an ASViewController
|
||||
|
||||
AsyncDisplayKit does not offer an equivalent to UICollectionViewController. Instead, you can use the flexibility of ASViewController to recreate any type of UI<UIKitSubclass>ViewController.
|
||||
AsyncDisplayKit does not offer an equivalent to UICollectionViewController. Instead, you can use the flexibility of ASViewController to recreate any type of UI<em>...</em>ViewController.
|
||||
|
||||
Consider, the following ASViewController subclass.
|
||||
|
||||
An `ASCollectionNode` is assigned to be managed by an `ASViewController` in its `initWithNode:` designated initializer method, thus making it a sort of ASCollectionNodeController.
|
||||
An ASCollectionNode is assigned to be managed by an `ASViewController` in its `-initWithNode:` designated initializer method, thus making it a sort of ASCollectionNodeController.
|
||||
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
@@ -72,16 +110,16 @@ init() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
This works just as well with any node such as an ASTableNode, ASPagerNode, etc.
|
||||
This works just as well with any node including as an ASTableNode, ASPagerNode, etc.
|
||||
|
||||
##Accessing the ASCollectionView##
|
||||
### Accessing the ASCollectionView
|
||||
If you've used previous versions of ASDK, you'll notice that `ASCollectionView` has been removed in favor of `ASCollectionNode`.
|
||||
|
||||
<div class = "note">
|
||||
`ASCollectionView` (an actual UICollectionView subclass) is still used as an internal property of `ASCollectionNode`. While it should not be created directly, it can still be used directly by accessing the .view property of an `ASCollectionNode`.
|
||||
</div>
|
||||
ASCollectionView, an actual UICollectionView subclass, is still used internally by ASCollectionNode. While it should not be created directly, it can still be used directly by accessing the .view property of an ASCollectionNode.
|
||||
|
||||
<div class = "note">Do not forget that anything that accesses a view using AsyncDisplayKit's node containers or nodes should be done in viewDidLoad or didLoad, respectively.</div>
|
||||
Don't forget that a node's <code>view</code> or <code>layer</code> property should only be accessed after viewDidLoad or didLoad, respectively, have been called.
|
||||
</div>
|
||||
|
||||
The LocationCollectionNodeController above accesses the ASCollectionView directly in viewDidLoad
|
||||
|
||||
@@ -113,17 +151,20 @@ override func viewDidLoad() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
##Table Row Height##
|
||||
### Cell Sizing and Layout
|
||||
|
||||
As discussed in the previous <a href = "containers-astablenode.html">`ASTableNode`</a> section, ASCollectionNodes and ASTableNodes do not need to keep track of the height of their ASCellNodes.
|
||||
As discussed in the <a href = "containers-astablenode.html">previous section</a>, ASCollectionNodes and ASTableNodes do not need to keep track of the height of their ASCellNodes.
|
||||
|
||||
***constrainedSizeForNode (also in table, but more important for collection)
|
||||
- check that (0,0) min and (infinity, infinity) max
|
||||
- example sample photo grid
|
||||
- popover, rotated -> how to get size constraint (USE constrainedSizeForNode to do simple divide by 3 width thing)
|
||||
- document itemSize (check what happens in ASDKgram)
|
||||
Right now, cells will grow to fit their constrained size and will be laid out by whatever UICollectionViewLayout you provide.
|
||||
|
||||
Soon, there will be a method such as ASTableNode's `-constrainedSizeForRow:` but at the moment, if you'd like to constrain the size of a cell used in a collection node, you need to wrap your layoutSpec object in an `ASStaticLayoutSpec` and provide it with a
|
||||
|
||||
### Examples
|
||||
|
||||
The most detailed example of laying out the cells of an ASCollectionNode is the <a href = "https://github.com/facebook/AsyncDisplayKit/tree/master/examples/CustomCollectionView">CustomCollectionView</a> app. It includes a Pinterest style cell layout using an ASCollectionNode and a custom `UICollectionViewLayout`.
|
||||
|
||||
#### More Sample Apps with ASCollectionNodes
|
||||
|
||||
##Sample Apps with ASCollectionNodes##
|
||||
<ul>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram</a></li>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/CatDealsCollectionView">CatDealsCollectionView</a></li>
|
||||
|
||||
@@ -5,29 +5,62 @@ permalink: /docs/containers-aspagernode.html
|
||||
next: display-node.html
|
||||
---
|
||||
|
||||
`ASPagerNode` is a subclass of `ASCollectionNode`.
|
||||
`ASPagerNode` is a subclass of `ASCollectionNode` with a specific UICollectionViewLayout used under the hood.
|
||||
|
||||
Using it allows you to produce a page style UI similar to what you'd create with UIKit's `UIPageViewController`. ASPager node currently supports staying on the correct page during rotation. It does _not_ currently support circular scrolling.
|
||||
Using it allows you to produce a page style UI similar to what you'd create with UIKit's UIPageViewController. ASPagerNode currently supports staying on the correct page during rotation. It does _not_ currently support circular scrolling.
|
||||
|
||||
The main dataSource methods are:
|
||||
|
||||
`- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode
|
||||
</pre>
|
||||
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
func numberOfPagesInPagerNode(pagerNode: ASPagerNode!) -> Int
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
and
|
||||
|
||||
`- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index
|
||||
</pre>
|
||||
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
func pagerNode(pagerNode: ASPagerNode!, nodeAtIndex index: Int) -> ASCellNode!
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
or
|
||||
|
||||
`- (ASCellNodeBlock)pagerNode:(ASPagerNode *)pagerNode nodeBlockAtIndex:(NSInteger)index` **_(recommended)_**
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNodeBlock)pagerNode:(ASPagerNode *)pagerNode nodeBlockAtIndex:(NSInteger)index`
|
||||
</pre>
|
||||
|
||||
These two methods, just as with `ASCollectionNode` and `ASTableNode` need to return either an `ASCellNode` or an `ASCellNodeBlock` - a block that creates a `ASCellNode` which can be run on a background thread.
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
func pagerNode(pagerNode: ASPagerNode!, nodeBlockAtIndex index: Int) -> ASCellNodeBlock!
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Note that both of these methods should not implement reuse (they will be called once per row). Unlike UIKit, these methods are not called when the row is just about to display.
|
||||
These two methods, just as with ASCollectionNode and ASTableNode need to return either an ASCellNode or an ASCellNodeBlock - a block that creates an `ASCellNode` and can be run on a background thread.
|
||||
|
||||
While `pagerNode:nodeAtIndex:` will be called on the main thread, `pagerNode:nodeBlockAtIndex:` is preferred because it concurrently allocates cell nodes, meaning that all of the `init:` methods for all of your subnodes are run in the background. **It is very important that node blocks be thread-safe** as they can be called on the main thread or a background queue.
|
||||
Note that neither methods should rely on cell reuse (they will be called once per row). Also, unlike UIKit, these methods are not called when the row is just about to display.
|
||||
|
||||
##Node Block Thread Safety Warning##
|
||||
While `-pagerNode:nodeAtIndex:` will be called on the main thread, `-pagerNode:nodeBlockAtIndex:` is preferred because it concurrently allocates cell nodes, meaning that the `-init:` method of each of your subnodes will be run in the background. **It is very important that node blocks be thread-safe** as they can be called on the main thread or a background queue.
|
||||
|
||||
### Node Block Thread Safety Warning
|
||||
|
||||
It is imperative that the data model be accessed outside of the node block. This means that it is highly unlikely that you should need to use the index inside of the block.
|
||||
|
||||
@@ -66,7 +99,7 @@ func pagerNode(pagerNode: ASPagerNode!, nodeBlockAtIndex index: Int) -> ASCellNo
|
||||
</div>
|
||||
</div>
|
||||
|
||||
##Use ASViewControllers For Optimal Performance##
|
||||
### Using an ASViewController For Optimal Performance
|
||||
|
||||
One especially useful pattern is to return an ASCellNode that is initialized with an existing UIViewController or ASViewController. For optimal performance, use an ASViewController.
|
||||
|
||||
@@ -107,9 +140,9 @@ func pagerNode(pagerNode: ASPagerNode!, nodeAtIndex index: Int) -> ASCellNode! {
|
||||
|
||||
In this example, you can see that the node is constructed using the `-initWithViewControllerBlock:` method. It is usually necessary to provide a cell created this way with a preferredFrameSize so that it can be laid out correctly.
|
||||
|
||||
##Sample Apps##
|
||||
### Sample Apps
|
||||
|
||||
Check out the following sample apps to see an ASPagerNode implemented within an app:
|
||||
Check out the following sample apps to see an ASPagerNode in action:
|
||||
<ul>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/PagerNode">PagerNode</a></li>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/VerticalWithinHorizontalScrolling">VerticalWithinHorizontalScrolling</a></li>
|
||||
|
||||
@@ -5,35 +5,80 @@ permalink: /docs/containers-astablenode.html
|
||||
next: containers-ascollectionnode.html
|
||||
---
|
||||
|
||||
`ASTableNode` is equivalent to UIKit's `UITableView` and can be used in place of any UITableView.
|
||||
ASTableNode is equivalent to UIKit's UITableView and can be used in place of any UITableView.
|
||||
|
||||
ASTableNode replaces UITableView's required method
|
||||
|
||||
`tableView:cellForRowAtIndexPath:`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle">
|
||||
<a data-lang="swift" class="swiftButton">Swift</a>
|
||||
<a data-lang="objective-c" class = "active objcButton">Objective-C</a>
|
||||
</span>
|
||||
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
</pre>
|
||||
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
with your choice of **_one_** of the following methods
|
||||
|
||||
`- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath`
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle">
|
||||
<a data-lang="swift" class="swiftButton">Swift</a>
|
||||
<a data-lang="objective-c" class = "active objcButton">Objective-C</a>
|
||||
</span>
|
||||
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
</pre>
|
||||
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func tableView(tableView: UITableView, nodeForRowAtIndexPath indexPath: NSIndexPath) -> ASCellNode
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
or
|
||||
|
||||
`- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath` **_(recommended)_**
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle">
|
||||
<a data-lang="swift" class="swiftButton">Swift</a>
|
||||
<a data-lang="objective-c" class = "active objcButton">Objective-C</a>
|
||||
</span>
|
||||
|
||||
These two methods, need to return either an <a href = "cell-node.html">`ASCellNode`</a> or an `ASCellNodeBlock`. An ASCellNodeBlock is a block that creates a ASCellNode which can be run on a background thread. Note that ASCellNodes are used by ASTableNode, ASCollectionNod and ASPagerNode.
|
||||
<div class = "code">
|
||||
<pre lang="objc" class="objcCode">
|
||||
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
</pre>
|
||||
|
||||
Note that both of these methods should not implement reuse (they will be called once per row). However, unlike UITableView, these methods are not called when the row is just about to display.
|
||||
<pre lang="swift" class = "swiftCode hidden">
|
||||
override func tableView(tableView: UITableView, nodeBlockForRowAtIndexPath indexPath: NSIndexPath) -> ASCellNodeBlock
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
####Node Blocks are Best####
|
||||
<div class = "note">
|
||||
It is recommended that you use the node block version of these methods so that your collection node will be able to prepare and display all of its cells concurrently. This means that all subnode initialization methods can be run in the background. Make sure to keep 'em thread safe.
|
||||
</div>
|
||||
|
||||
While `tableView:nodeForRowAtIndexPath:` will be called on the main thread, `tableView:nodeBlockForRowAtIndexPath:` is preferred because it concurrently allocates cell nodes. This means that all of the init: methods for all of your subnodes are run in the background.
|
||||
These two methods, need to return either an <a href = "cell-node.html">ASCellNode</a> or an `ASCellNodeBlock`. An ASCellNodeBlock is a block that creates a ASCellNode which can be run on a background thread. Note that ASCellNodes are used by ASTableNode, ASCollectionNode and ASPagerNode.
|
||||
|
||||
##Replace UITableViewController with ASViewController##
|
||||
Note that neither of these methods require a reuse mechanism.
|
||||
|
||||
### Replacing UITableViewController with ASViewController
|
||||
|
||||
AsyncDisplayKit does not offer an equivalent to UITableViewController. Instead, use an ASViewController initialized with an ASTableNode.
|
||||
|
||||
Consider, again, the ASViewController subclass - PhotoFeedNodeController - from the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> that uses a table node as its managed node.
|
||||
|
||||
An `ASTableNode` is assigned to be managed by an `ASViewController` in its `initWithNode:` designated initializer method.
|
||||
An `ASTableNode` is assigned to be managed by an `ASViewController` in its `-initWithNode:` designated initializer method.
|
||||
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
@@ -69,11 +114,11 @@ func initWithModel(models: Array<Model>) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
##Node Block Thread Safety Warning##
|
||||
### Node Block Thread Safety Warning
|
||||
|
||||
It is very important that node blocks be thread-safe. One aspect of that is ensuring that the data model is accessed _outside_ of the node block. Therefore, it is unlikely that you should need to use the index inside of the block.
|
||||
|
||||
Consider the following `tableView:nodeBlockForRowAtIndexPath:` method from the `PhotoFeedNodeController.m` file in the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a>.
|
||||
Consider the following `-tableView:nodeBlockForRowAtIndexPath:` method from the `PhotoFeedNodeController.m` file in the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a>.
|
||||
|
||||
In the example below, you can see how the index is used to access the photo model before creating the node block.
|
||||
|
||||
@@ -86,13 +131,13 @@ In the example below, you can see how the index is used to access the photo mode
|
||||
PhotoModel *photoModel = [_photoFeed objectAtIndex:indexPath.row];
|
||||
|
||||
// this may be executed on a background thread - it is important to make sure it is thread safe
|
||||
ASCellNode *(^ASCellNodeBlock)() = ^ASCellNode *() {
|
||||
ASCellNode *(^cellNodeBlock)() = ^ASCellNode *() {
|
||||
PhotoCellNode *cellNode = [[PhotoCellNode alloc] initWithPhoto:photoModel];
|
||||
cellNode.delegate = self;
|
||||
return cellNode;
|
||||
};
|
||||
|
||||
return ASCellNodeBlock;
|
||||
return cellNodeBlock;
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -116,16 +161,17 @@ func tableView(tableView: UITableView!, nodeBlockForRowAtIndexPath indexPath: NS
|
||||
</div>
|
||||
|
||||
|
||||
##Accessing the ASTableView##
|
||||
### Accessing the ASTableView
|
||||
|
||||
If you've used previous versions of ASDK, you'll notice that `ASTableView` has been removed in favor of `ASTableNode`.
|
||||
|
||||
<div class = "note">
|
||||
`ASTableView` (an actual UITableView subclass) is still used as an internal property of `ASTableNode`. While it should not be created directly, it can still be used directly by accessing the .view property of an `ASTableNode`.
|
||||
ASTableView, an actual UITableView subclass, is still used internally by ASTableNode. While it should not be created directly, it can still be used directly by accessing the .view property of an ASTableNode.
|
||||
|
||||
Don't forget that a node's <code>view</code> or <code>layer</code> property should only be accessed after viewDidLoad or didLoad, respectively, have been called.
|
||||
</div>
|
||||
|
||||
**Do not forget that anything that accesses a view using AsyncDisplayKit's node containers or nodes should be done in viewDidLoad or didLoad, respectively.**
|
||||
|
||||
For example, you may want to set a table's separator style property. This can be done by accessing the table node's view in the `viewDidLoad:` method as seen in the example below.
|
||||
For example, you may want to set a table's separator style property. This can be done by accessing the table node's view in the `-viewDidLoad:` method as seen in the example below.
|
||||
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
@@ -153,24 +199,27 @@ override func viewDidLoad() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
##Table Row Height##
|
||||
### Table Row Height
|
||||
|
||||
An important thing to notice is that `ASTableNode` does not provide an equivalent to `UITableView`'s
|
||||
An important thing to notice is that `ASTableNode` does not provide an equivalent to `UITableView`'s `-tableView:heightForRowAtIndexPath:`.
|
||||
|
||||
`tableView:heightForRowAtIndexPath:`
|
||||
This is because nodes are responsible for determining their own height based on the provided constraints. This means you no longer have to write code to determine this detail at the view controller level.
|
||||
|
||||
This is because in AsyncDisplayKit, nodes are responsible for determining their height themselves which means you no longer have to write code to determine this detail at the view controller level.
|
||||
A node defines its height by way of the layoutSpec returned in the `-layoutSpecThatFits:` method. All nodes given a constrained size are able to calculate their desired size.
|
||||
|
||||
A node defines its height by way of its layoutSpec returned in the `- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize` method. All nodes given a constrained size are able to calculate their desired size. **Note that nodes that don't have an inherent size, such as an image or map) must set their `.preferredFrameSize` property.**
|
||||
<div class = "note">
|
||||
By default, a tableNode provides its cells with a size range constraint where the minimum width is the tableNode's width and a minimum height is 0. The maximim width is also the tableNode's width but the maximum height is FLT_MAX.
|
||||
|
||||
**By default, the size range provided to the cell is the width of the table and zero height (min) and maximum is width of table and infinite height (max).**
|
||||
This is all to say, a tableNode's cells will always fill the full width of the tableNode, but their height is flexible making self-sizing cells something that happens automatically.
|
||||
</div>
|
||||
|
||||
This is the magic of the `ASTableView`. From the level of the ASCellNode, the cell can very easily control it’s height and the tableNode will automatically adjust accordingly. For an example of this in action, see how the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> inserts comments below comments at a later time, increasing the height magically!
|
||||
If you call `-setNeedsLayout` on an ASCellNode, it will automatically perform another layout pass and if its overall desired size has changed, the table or collection will be informed and will update itself.
|
||||
|
||||
If you call `-setNeedsLayout` on an `ASCellNode`, it will automatically be perform its layout measurement again and if its overall desired size has changed, the table or collection will be informed and update. This is different from UIKit where normally you would have to call reload row / item. This saves tons of code, check out the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> to see side by side implementations of an UITableView and ASTableNode implemented social media feed.
|
||||
This is different from UIKit where normally you would have to call reload row / item. This saves tons of code, check out the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> to see side by side implementations of an UITableView and ASTableNode implemented social media feed.
|
||||
|
||||
##Sample Apps with ASTableNodes##
|
||||
### Sample Apps with ASTableNodes
|
||||
<ul>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram</a></li>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram</a></li>
|
||||
<li><a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/Kittens">Kittens</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -7,17 +7,17 @@ next: containers-astablenode.html
|
||||
|
||||
`ASViewController` is a subclass of `UIViewController` that adds several useful features for hosting `ASDisplayNode` hierarchies.
|
||||
|
||||
An `ASViewController` can be used in place of any `UIViewController` - including within a `UINavigationController`, `UITabBarController` and `UISpitViewController` or as a modal view controller.
|
||||
An ASViewController can be used in place of any UIViewController - including within a UINavigationController, UITabBarController and UISpitViewController or as a modal view controller.
|
||||
|
||||
One of the main benefits to using an `ASViewController` is to save memory. An `ASViewController` that goes off screen will automatically reduce the size of the fetch data and display ranges of any of its children. This is key for memory management in large applications.
|
||||
One of the main benefits to using an ASViewController is to save memory. An ASViewController that goes off screen will automatically reduce the size of the fetch data and display ranges of any of its children. This is key for memory management in large applications.
|
||||
|
||||
More features will be added over time, so it is a good idea to base your view controllers off of this class.
|
||||
|
||||
A `UIViewController` provides a view of its own. An `ASViewController` is assigned a node to manage in its designated initializer `initWithNode:`.
|
||||
A UIViewController provides a view of its own. An ASViewController is assigned a node to manage in its designated initializer `-initWithNode:`.
|
||||
|
||||
Consider the following `ASViewController` subclass `PhotoFeedNodeController` from the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> that would like to use a table node as its managed node.
|
||||
Consider the following ASViewController subclass, `PhotoFeedNodeController`, from the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> that would like to use a table node as its managed node.
|
||||
|
||||
This table node is assigned to the `ASViewController` in its `initWithNode:` designated initializer method.
|
||||
This table node is assigned to the ASViewController in its `-initWithNode:` designated initializer method.
|
||||
|
||||
<div class = "highlight-group">
|
||||
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
|
||||
@@ -55,6 +55,6 @@ func initWithModel(models: Array<Model>) {
|
||||
</div>
|
||||
|
||||
<div class = "note">
|
||||
If your app already has a complex view controller hierarchy, it is perfectly fine to have all of them subclass `ASViewController`. That is to say, even if you don't use `ASViewController`'s designated initializer `initiWithNode:`, and only use the `ASViewController` in the manner of a traditional `UIVieWController`, this will give you the additional node support if you choose to adopt it in different areas your application.
|
||||
If your app already has a complex view controller hierarchy, it is perfectly fine to have all of them subclass ASViewController. That is to say, even if you don't use `ASViewController`'s designated initializer `-initiWithNode:`, and only use the `ASViewController` in the manner of a traditional `UIVieWController`, this will give you the additional node support if you choose to adopt it in different areas your application.
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ permalink: /docs/containers-overview.html
|
||||
next: containers-asviewcontroller.html
|
||||
---
|
||||
|
||||
##Use Nodes in Node Containers##
|
||||
### Use Nodes in Node Containers
|
||||
It is highly recommended that you use AsyncDisplayKit's nodes within a node container. AsyncDisplayKit offers the following node containers
|
||||
|
||||
- `ASViewController` in place of UIKit's `UIViewController`
|
||||
@@ -17,7 +17,7 @@ Example code and specific sample projects are highlighted in the documentation f
|
||||
|
||||
For a detailed description on porting an existing UIKit app to AsyncDisplayKit, read the <a href = "porting-guide.html">porting guide</a>.
|
||||
|
||||
####What do I Gain by Using a Node Container?####
|
||||
### What do I Gain by Using a Node Container?
|
||||
|
||||
A node container automatically manages the <a href = "intelligent-preloading.html">intelligent preloading</a> of its nodes. This means that all of the node's layout measurement, data fetching, decoding and rendering will be done asynchronously. Among other conveniences, this is why it is reccomended to use nodes within a container node.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Whle this example is extremely simple, it gives you an idea of how to use a layo
|
||||
|
||||
### ASLayoutable
|
||||
|
||||
Layout spec's children can be any object whose class conforms to the `<ASLayoutable>` protocol. All nodes, as well as all layout specs conform to the `<ASLayoutable>` protocol. This means that your layout can be build up in composable chunks until you have what you want.
|
||||
Layout spec's children can be any object whose class conforms to the `<ASLayoutable>` protocol. All nodes, as well as all layout specs conform to the `<ASLayoutable>` protocol. This means that your layout can be built up in composable chunks until you have what you want.
|
||||
|
||||
Say you wanted to add 8 pts of padding to the stack you've already set up:
|
||||
|
||||
|
||||
@@ -81,14 +81,17 @@ p, ul, ol {
|
||||
|
||||
code {
|
||||
letter-spacing: 0.02em;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
font-weight: 700;
|
||||
color: #008ED4;
|
||||
font-size: 14px;
|
||||
vertical-align: baseline;
|
||||
font-family: 'Droid Sans Mono',sans-serif;
|
||||
}
|
||||
|
||||
/*
|
||||
p code, span code, li code {
|
||||
border: 1px solid rgb(220, 220, 220);
|
||||
background-color: rgba(90, 140, 140, 0.1);
|
||||
}
|
||||
}*/
|
||||
|
||||
.highlight pre, .redhighlight pre {
|
||||
font-size: 13px;
|
||||
|
||||
Reference in New Issue
Block a user