mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-06-19 17:43:23 +08:00
Merge branch 'gh-pages' of github.com:facebook/AsyncDisplayKit into gh-pages
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
- getting-started
|
||||
- philosophy
|
||||
- installation
|
||||
- references
|
||||
- title: Core Concepts
|
||||
items:
|
||||
- intelligent-preloading
|
||||
@@ -50,7 +49,9 @@
|
||||
- batch-fetching-api
|
||||
- image-modification-block
|
||||
- placeholder-fade-duration
|
||||
- title: Debug Tools
|
||||
items:
|
||||
- debug-tool-hit-test-visualization
|
||||
- debug-tool-pixel-scaling
|
||||
- title: Beta
|
||||
items:
|
||||
- implicit-hierarchy-mgmt
|
||||
- layout-transition-api
|
||||
|
||||
@@ -19,6 +19,5 @@ The following layoutSpecs allow you to layout a single children:
|
||||
* **ASCenterLayoutSpec** centers a component in the available space.
|
||||
* **ASRatioLayoutSpec** lays out a component at a fixed aspect ratio. Great for images, gifs and videos.
|
||||
* **ASRelativeLayoutSpec** lays out a component and positions it within the layout bounds according to vertical and horizontal positional specifiers. Similar to the “9-part” image areas, a child can be positioned at any of the 4 corners, or the middle of any of the 4 edges, as well as the center.
|
||||
*
|
||||
|
||||
##Strategy
|
||||
|
||||
@@ -9,7 +9,7 @@ next: containers-asviewcontroller.html
|
||||
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`
|
||||
- `ASCollectioNode` in place of UIKit's `UICollectionView`
|
||||
- `ASCollectionNode` in place of UIKit's `UICollectionView`
|
||||
- `ASPagerNode` in place of UIKit's `UIPageViewController`
|
||||
- `ASTableNode` in place of UIKit's `UITableView`
|
||||
|
||||
|
||||
@@ -5,4 +5,14 @@ permalink: /docs/hit-test-slop.html
|
||||
next: batch-fetching-api.html
|
||||
---
|
||||
|
||||
<div class = "warning">😑 This page is coming soon...</div>
|
||||
`ASDisplayNode` has a `hitTestSlop` property of type `UIEdgeInsets` that when set to a non-zero inset, increase the bounds for hit testing to make it easier to tap or perform gestures on this node.
|
||||
|
||||
ASDisplayNode is the base class for all nodes, so this property is available on any of AsyncDisplayKit's nodes.
|
||||
|
||||
Note:
|
||||
<ul>
|
||||
<li>the default value is UIEdgeInsetsZero</li>
|
||||
<li>This affects the default implementation of `-hitTest` and `-pointInside`, so subclasses should call super if you override it and want hitTestSlop applied.</li>
|
||||
</ul>
|
||||
|
||||
A node's ability to capture touch events is restricted by its parent's bounds + parent hitTestSlop UIEdgeInsets. Should you want to extend the hitTestSlop of a child outside its parent's bounds, simply extend the parent node's hitTestSlop to include the child's hitTestSlop needs.
|
||||
|
||||
142
_docs/implicit-hierarchy-mgmt.md
Normal file
142
_docs/implicit-hierarchy-mgmt.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Implicit Node Hierarchy Mgmt
|
||||
layout: docs
|
||||
permalink: /docs/implicit-hierarchy-mgmt.html
|
||||
next: debug-hit-test.html
|
||||
---
|
||||
|
||||
This feature - created by ASDK rockstar <a href="https://github.com/facebook/AsyncDisplayKit/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Alevi+">@levi</a> - was built to support the AsyncDisplayKit Layout Transition API. However, apps using AsyncDisplayKit that don't require animations can still benefit from the reduction in code size that this feature enables.
|
||||
|
||||
**This feature will soon be enabled by default.**
|
||||
|
||||
<div class = "note">
|
||||
Implicit Node Hierarchy Management is implemented using ASLayoutSpecs. If you are unfamiliar with that concept, please read that documentation (INSERT LINK) first. <br><br>
|
||||
To recap, an ASLayoutSpec completely describes the UI of a view in your app by specifying the **hierarchy state of a node and its subnodes**. An ASLayoutSpec is returned by a node from its <br><br>
|
||||
`- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize` <br><br>
|
||||
method.
|
||||
</div>
|
||||
|
||||
When enabled, INHM, means that your nodes no longer require `addSubnode:` or `removeFromSupernode` method calls. The presence or absence of the INHM node _and_ its subnodes are determined in the layoutSpecThatFits: method.
|
||||
|
||||
**Note that the subnodes of any node with this property set will inherit INHM, so it is only neccessary to put it on the highest level node. Most likely that will be an ASTableNode, ASCollectionNode or ASPagerNode.**
|
||||
|
||||
####Example####
|
||||
Consider the following `ASCellNode` subclass `PhotoCellNode` from the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples/ASDKgram">ASDKgram sample app</a> which produces a simple social media photo feed UI.
|
||||
|
||||
```objective-c
|
||||
- (instancetype)initWithPhotoObject:(PhotoModel *)photo;
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
|
||||
self.usesImplicitHierarchyManagement = YES;
|
||||
|
||||
_photoModel = photo;
|
||||
|
||||
_userAvatarImageView = [[ASNetworkImageNode alloc] init];
|
||||
_userAvatarImageView.URL = photo.ownerUserProfile.userPicURL;
|
||||
|
||||
_photoImageView = [[ASNetworkImageNode alloc] init];
|
||||
_photoImageView.URL = photo.URL;
|
||||
|
||||
_userNameLabel = [[ASTextNode alloc] init];
|
||||
_userNameLabel.attributedString = [photo.ownerUserProfile usernameAttributedStringWithFontSize:FONT_SIZE];
|
||||
|
||||
_photoLocationLabel = [[ASTextNode alloc] init];
|
||||
[photo.location reverseGeocodedLocationWithCompletionBlock:^(LocationModel *locationModel) {
|
||||
if (locationModel == _photoModel.location) {
|
||||
_photoLocationLabel.attributedString = [photo locationAttributedStringWithFontSize:FONT_SIZE];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
}];
|
||||
|
||||
_photoCommentsView = [[CommentsNode alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
By setting usesImplicitHierarchyManagement to YES on the ASCellNode, we _no longer_ need to call `addSubnode:` for each of the ASCellNode's subnodes.
|
||||
|
||||
Several of the elements in this cell - `_userAvatarImageView`, `_photoImageView`, `_photoLocationLabel` and `_photoCommentsView` - depend on seperate data fetches from the network that could return at any time.
|
||||
|
||||
Implicit Hierarchy Management knows whether or not to include these elements in the UI based on information provided in the cell's ASLayoutSpec.
|
||||
|
||||
**It is your job to construct a `layoutSpecThatFits:` that handles how the UI should look with and without these elements.**
|
||||
|
||||
Consider the layoutSpecThatFits: method for the ASCellNode subclass
|
||||
|
||||
```objective-c
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
// username / photo location header vertical stack
|
||||
_photoLocationLabel.flexShrink = YES;
|
||||
_userNameLabel.flexShrink = YES;
|
||||
|
||||
ASStackLayoutSpec *headerSubStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
headerSubStack.flexShrink = YES;
|
||||
if (_photoLocationLabel.attributedString) {
|
||||
[headerSubStack setChildren:@[_userNameLabel, _photoLocationLabel]];
|
||||
} else {
|
||||
[headerSubStack setChildren:@[_userNameLabel]];
|
||||
}
|
||||
|
||||
// header stack
|
||||
_userAvatarImageView.preferredFrameSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT); // constrain avatar image frame size
|
||||
|
||||
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
|
||||
spacer.flexGrow = YES;
|
||||
|
||||
UIEdgeInsets avatarInsets = UIEdgeInsetsMake(HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER, HORIZONTAL_BUFFER);
|
||||
ASInsetLayoutSpec *avatarInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:avatarInsets child:_userAvatarImageView];
|
||||
|
||||
ASStackLayoutSpec *headerStack = [ASStackLayoutSpec horizontalStackLayoutSpec];
|
||||
headerStack.alignItems = ASStackLayoutAlignItemsCenter; // center items vertically in horizontal stack
|
||||
headerStack.justifyContent = ASStackLayoutJustifyContentStart; // justify content to the left side of the header stack
|
||||
[headerStack setChildren:@[avatarInset, headerSubStack, spacer]];
|
||||
|
||||
// header inset stack
|
||||
UIEdgeInsets insets = UIEdgeInsetsMake(0, HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER);
|
||||
ASInsetLayoutSpec *headerWithInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:headerStack];
|
||||
|
||||
// footer inset stack
|
||||
UIEdgeInsets footerInsets = UIEdgeInsetsMake(VERTICAL_BUFFER, HORIZONTAL_BUFFER, VERTICAL_BUFFER, HORIZONTAL_BUFFER);
|
||||
ASInsetLayoutSpec *footerWithInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:footerInsets child:_photoCommentsView];
|
||||
|
||||
// vertical stack
|
||||
CGFloat cellWidth = constrainedSize.max.width;
|
||||
_photoImageView.preferredFrameSize = CGSizeMake(cellWidth, cellWidth); // constrain photo frame size
|
||||
|
||||
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
verticalStack.alignItems = ASStackLayoutAlignItemsStretch; // stretch headerStack to fill horizontal space
|
||||
[verticalStack setChildren:@[headerWithInset, _photoImageView, footerWithInset]];
|
||||
|
||||
return verticalStack;
|
||||
}
|
||||
```
|
||||
|
||||
Here you can see that I set the children of my `headerSubStack` to depending on wehther or not the `_photoLocationLabel` attributed string has returned from the reverseGeocode process yet.
|
||||
|
||||
The `_userAvatarImageView`, `_photoImageView`, and `_photoCommentsView` are added into the ASLayoutSpec, but will not show up until their data fetches return.
|
||||
|
||||
####Updating an ASLayoutSpec####
|
||||
|
||||
**If something happens that you know will change your `ASLayoutSpec`, it is your job to call `-setNeedsLayout`** (equivalent to `transitionLayout:duration:0` that will be mentioned in the Transition Layout API). As can be seen in the completion block of the photo.location reverseGeocodedLocationWithCompletionBlock: call above.
|
||||
|
||||
An appropriately constructed ASLayoutSpec will know which subnodes need to be added, removed or animated.
|
||||
|
||||
If you try out the ASDKgram sample app after looking at the code above, you can see how simple it is to code a cell node thats layout is responsive to numerous, individual data fetches and returns. While the ASLayoutSpec is coded in a way that leaves holes for the avatar and photo to populate, you can see how the cell's height will automatically adjust to accomodate the comments node at the bottom of the photo.
|
||||
|
||||
This is just a simple example, but this feature has many more powerful uses.
|
||||
|
||||
####To Use####
|
||||
|
||||
- import `"ASDisplayNode+Beta.h"`
|
||||
- set the `.usesImplicitHierarchyManagement = YES` on the node that you would like managed.
|
||||
|
||||
**Note that the subnodes of any node with this property set will inherit the property, so it is only neccessary to put it on the highest level node. Most likely that will be an ASTableNode, ASCollectionNode or ASPagerNode.**
|
||||
|
||||
Please check it out and let us know what you think at <a href="https://github.com/facebook/AsyncDisplayKit/pull/1156">PR #1156</a>!
|
||||
@@ -4,32 +4,29 @@ layout: docs
|
||||
permalink: /docs/installation.html
|
||||
next: references.html
|
||||
---
|
||||
|
||||
###CocoaPods
|
||||
AsyncDisplayKit is available on <a href="http://cocoapods.org">CocoaPods</a>. Add the following to your Podfile:
|
||||
|
||||
ASDK is available on <a href="http://cocoapods.org">CocoaPods</a>. Add the following to your Podfile:
|
||||
|
||||
```objective-c
|
||||
pod 'AsyncDisplayKit'
|
||||
```
|
||||
|
||||
ASDK can also be used as a regular static library:
|
||||
###Carthage
|
||||
AsyncDisplayKit is also available through <a href="https://github.com/Carthage/Carthage">Carthage</a>. Add the following to your Cartfile:
|
||||
|
||||
Copy the project to your codebase manually, adding `AsyncDisplayKit.xcodeproj` to your workspace. Add `libAsyncDisplayKit.a`, AssetsLibrary, and Photos to the "Link Binary With Libraries" build phase. Include `-lc++ -ObjC` in your project linker flags.
|
||||
```objective-c
|
||||
github "facebook/AsyncDisplayKit"
|
||||
```
|
||||
|
||||
Run ‘carthage update’ in Terminal and to fetch and build the AsyncDisplayKit library. This will create a folder named Carthage in your app’s root folder. In that folder there will be a ‘Build’ folder from where you have to drag the frameworks you want to use into the “Linked Frameworks and Libraries” section in Xcode.
|
||||
|
||||
###Static Library
|
||||
AsyncDisplayKit can also be used as a regular static library
|
||||
Copy the project to your codebase manually, adding `AsyncDisplayKit.xcodeproj` to your workspace. Add `libAsyncDisplayKit.a`, AssetsLibrary, and Photos to the "Link Binary With Libraries" build phase. Include `-lc++ -ObjC` in your project linker flags.
|
||||
|
||||
###Importing AsyncDisplayKit
|
||||
Import the framework header, or create an <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html">Objective-C bridging header</a> if you're using **Swift**:
|
||||
|
||||
```objective-c
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
```
|
||||
|
||||
###Carthage
|
||||
|
||||
ASDK is available through <a href="https://github.com/Carthage/Carthage">Carthage</a>. Add the following to your Cartfile:
|
||||
|
||||
```objective-c
|
||||
github "facebook/AsyncDisplayKit"
|
||||
```
|
||||
Run ‘carthage update’ in Terminal and to fetch and build the ASDK library. This will create a folder named Carthage in your app’s root folder. In that folder there will be a ‘Build’ folder from where you have to drag the frameworks you want to use into the “Linked Frameworks and Libraries” section in Xcode.
|
||||
|
||||
Learn more about <a href="https://github.com/Carthage/Carthage/blob/master/README.md">Carthage</a>.
|
||||
|
||||
121
_docs/layout-transition-api.md
Normal file
121
_docs/layout-transition-api.md
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
title: Layout Transition API
|
||||
layout: docs
|
||||
permalink: /docs/layout-transition-api.html
|
||||
next: layout-transition-api.html
|
||||
---
|
||||
###Overview
|
||||
<a href="https://github.com/facebook/AsyncDisplayKit/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Alevi+">@levi</a> designed this API to make all animations with AsyncDisplayKit easy - even transforming an entire set of views into a completely different set of views!
|
||||
|
||||
With this system, you simply specify the desired layout and AsyncDisplayKit will do the work to figure out differences from the current layout. It will automatically and new elements, remove unneeded elements after the transiton and update the position of any existing elements.
|
||||
|
||||
There are also easy to use APIs that allow you to fully customize the starting position of newly introduced elements, as well as the ending position of removed elements.
|
||||
|
||||
## Animating between layouts
|
||||
|
||||
The layout transition API makes it easy to animate between a node's generated layouts in response to some internal state change in a node.
|
||||
|
||||
Imagine you wanted to implement this sign up form and animate in the new field when tapping the next button:
|
||||
|
||||

|
||||
|
||||
A standard way to implement this would be to create a container node called `SignupNode` that includes two `FieldNode`s and a button node as subnodes. We'll include a property on the `SignupNode` called `fieldState` that will be used to select which `FieldNode` to show when the node calculates its layout. The internal layout spec of the `SignupNode` container would look something like this:
|
||||
|
||||
```objective-c
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
FieldNode *field;
|
||||
if (self.fieldState == SignupNodeName) {
|
||||
field = self.nameField;
|
||||
} else {
|
||||
field = self.ageField;
|
||||
}
|
||||
|
||||
ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init];
|
||||
[stack setChildren:@[field, self.buttonNode]];
|
||||
|
||||
UIEdgeInsets insets = UIEdgeInsetsMake(15.0, 15.0, 15.0, 15.0);
|
||||
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:stack];
|
||||
}
|
||||
```
|
||||
|
||||
To trigger a transition from the `nameField` to the `ageField` in this example, we'll update the SignupNode's fieldState property and begin the transition with `transitionLayoutWithAnimation:`. This method will invalidate the current calculated layout and recompute a new layout with the `ageField` now in the stack.
|
||||
|
||||
```objective-c
|
||||
self.signupNode.fieldState = SignupNodeAge;
|
||||
[self.signupNode transitionLayoutWithAnimation:YES];
|
||||
```
|
||||
|
||||
In the default implementation of this API, the layout will recalculate the new layout and use its sublayouts to size and position the `SignupNode`'s subnodes without animation. Future versions of this API will likely include a default animation between layouts and we're open to feedback on what you'd like to see here. However, we'll need to implement a custom animation block to handle the signup form case.
|
||||
|
||||
The example below represents an override of `animateLayoutTransition:` in `SignupNode`. This method is called after the new layout has been calculated via `transitionLayoutWithAnimation:` and in the implementation we'll perform a specific animation based upon the `fieldState` property that was set before the animation was triggered.
|
||||
|
||||
```objective-c
|
||||
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context
|
||||
{
|
||||
if (self.fieldState == SignupNodeName) {
|
||||
CGRect initialNameFrame = [context initialFrameForNode:self.ageField];
|
||||
initialNameFrame.origin.x += initialNameFrame.size.width;
|
||||
self.nameField.frame = initialNameFrame;
|
||||
self.nameField.alpha = 0.0;
|
||||
CGRect finalEmailFrame = [context finalFrameForNode:self.nameField];
|
||||
finalEmailFrame.origin.x -= finalEmailFrame.size.width;
|
||||
[UIView animateWithDuration:0.4 animations:^{
|
||||
self.nameField.frame = [context finalFrameForNode:self.nameField];
|
||||
self.nameField.alpha = 1.0;
|
||||
self.ageField.frame = finalEmailFrame;
|
||||
self.ageField.alpha = 0.0;
|
||||
} completion:^(BOOL finished) {
|
||||
[context completeTransition:finished];
|
||||
}];
|
||||
} else {
|
||||
CGRect initialAgeFrame = [context initialFrameForNode:self.nameField];
|
||||
initialAgeFrame.origin.x += initialAgeFrame.size.width;
|
||||
self.ageField.frame = initialAgeFrame;
|
||||
self.ageField.alpha = 0.0;
|
||||
CGRect finalNameFrame = [context finalFrameForNode:self.ageField];
|
||||
finalNameFrame.origin.x -= finalNameFrame.size.width;
|
||||
[UIView animateWithDuration:0.4 animations:^{
|
||||
self.ageField.frame = [context finalFrameForNode:self.ageField];
|
||||
self.ageField.alpha = 1.0;
|
||||
self.nameField.frame = finalNameFrame;
|
||||
self.nameField.alpha = 0.0;
|
||||
} completion:^(BOOL finished) {
|
||||
[context completeTransition:finished];
|
||||
}];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The passed [ASContextTransitioning](https://github.com/facebook/AsyncDisplayKit/blob/master/AsyncDisplayKit/ASContextTransitioning.h) context object in this method contains relevant information to help you determine the state of the nodes before and after the transition. It includes getters into old and new constrained sizes, inserted and removed nodes, and even the raw old and new `ASLayout` objects. In the `SignupNode` example, we're using it to determine the frame for each of the fields and animate them in an out of place.
|
||||
|
||||
It is imperative to call `completeTransition:` on the context object once your animation has finished, as it will perform the necessary internal steps for the newly calculated layout to become the current `calculatedLayout`.
|
||||
|
||||
Note that there hasn't been a use of `addSubnode:` or `removeFromSupernode` during the transition. AsyncDisplayKit's layout transition API analyzes the differences in the node hierarchy between the old and new layout, implicitly performing node insertions and removals for automatically. Nodes are inserted before your implementation of `animateLayoutTransition:` is called and this is a good place to manually manage the hierarchy before you begin the animation. Removals are preformed in `didCompleteLayoutTransition:` after you call `completeTransition:` on the context object. If you need to manually perform deletions, override `didCompleteLayoutTransition:` and perform your custom operations. Note that this will override the default behavior and it is recommended to either call `super` or walk through the `removedSubnodes` getter in the context object to perform the cleanup.
|
||||
|
||||
Passing `NO` to `transitionLayoutWithAnimation:` will still run through your `animateLayoutTransition:` and `didCompleteLayoutTransition:` implementations with the `[context isAnimated]` property set to `NO`. It is your choice on how to handle this case — if at all. An easy way to provide a default implementation this is to call `super`:
|
||||
```objective-c
|
||||
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context
|
||||
{
|
||||
if ([context isAnimated]) {
|
||||
// perform animation
|
||||
} else {
|
||||
[super animateLayoutTransition:context];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Animating constrained size changes
|
||||
|
||||
There will be times you'll simply want to respond to bounds changes to your node and animate the recalculation of its layout. To handle this case, call `transitionLayoutWithSizeRange:animated:` on your node. This method is similar to `transitionLayoutWithAnimation:`, but will not trigger an animation if the passed `ASSizeRange` is equal to the current `constrainedSizeForCalculatedLayout` value. This is great for responding to rotation events and view controller size changes:
|
||||
```objective-c
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
[self.node transitionLayoutWithSizeRange:ASSizeRangeMake(size, size) animated:YES];
|
||||
} completion:nil];
|
||||
}
|
||||
```
|
||||
|
||||
Please check it out and let @levi know what you think at <a href="https://github.com/facebook/AsyncDisplayKit/pull/1156">PR #1156</a>!
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
title: References
|
||||
layout: docs
|
||||
permalink: /docs/references.html
|
||||
next: intelligent-preloading.html
|
||||
---
|
||||
|
||||
###Join our Slack!
|
||||
|
||||
For general discussion, announcements and help. Email AsyncDisplayKit@gmail.com for an invite.
|
||||
|
||||
###Learn more
|
||||
- Get the <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples">sample projects</a>
|
||||
- Browse the <a href="/appledocs.html">API reference</a>
|
||||
- Watch the <a href="http://vimeo.com/103589245">NSLondon talk</a> or the <a href="https://www.youtube.com/watch?v=RY_X7l1g79Q">NSSpain talk</a>
|
||||
|
||||
###Apps (that we know of) that use ASDK
|
||||
- <a href="https://itunes.apple.com/us/app/pinterest/id429047995?mt=8">Pinterest</a>
|
||||
- <a href="https://itunes.apple.com/us/app/this-is-money/id768740884?mt=8">This is Money</a>
|
||||
- and many more that we don't have permission to put here...
|
||||
|
||||
<a href="mailto:asyncdisplaykit@gmail.com?subject=An App for the Docs!">Email us</a> to add your app to this list.
|
||||
20
resources.md
20
resources.md
@@ -4,16 +4,24 @@ layout: resources
|
||||
permalink: /resources.html
|
||||
---
|
||||
|
||||
<h2>Video Resources</h2>
|
||||
###Slack
|
||||
|
||||
Join 60+ AsyncDisplayKit developers for real-time debugging, the latest updates, and asynchronous banter. Email AsyncDisplayKit(at)gmail.com for an invite.
|
||||
|
||||
###Sample Projects
|
||||
Scroll through the examples/README.md to see screenshots / gifs of the numerous <a href="https://github.com/facebook/AsyncDisplayKit/tree/master/examples">sample projects</a>.
|
||||
|
||||
###Videos
|
||||
<ul>
|
||||
<li><a href = "https://www.youtube.com/watch?v=RY_X7l1g79Q">AsyncDisplayKit 2.0: Intelligent User Interfaces - NSSpain 2015</a>
|
||||
<li><a href = "https://www.youtube.com/watch?v=ZPL4Nse76oY">Effortless Responsiveness with AsyncDisplayKit - MCE 2015</a>
|
||||
<li><a href = "https://www.youtube.com/watch?v=h4QDbgB7RLo">Asynchronous UI - NSLondon 2014</a>
|
||||
<li><a href = "https://www.youtube.com/watch?v=RY_X7l1g79Q">AsyncDisplayKit 2.0: Intelligent User Interfaces [NSSpain 2015]</a>
|
||||
<li><a href = "https://www.youtube.com/watch?v=ZPL4Nse76oY">Effortless Responsiveness with AsyncDisplayKit [MCE 2015]</a>
|
||||
<li><a href = "https://www.youtube.com/watch?v=h4QDbgB7RLo">Asynchronous UI [NSLondon 2014]</a>
|
||||
</ul>
|
||||
|
||||
<h2>Layout Resources</h2>
|
||||
<h5>ASDK's powerful layout system is based on the CSS FlexBox model. These sites are useful for learning the basic concepts of this system if you aren't familiar."</h5>
|
||||
###Layout Resources
|
||||
AsyncDisplayKit's powerful layout system is based on the CSS FlexBox model. These sites are useful for learning the basics of this system.
|
||||
<ul>
|
||||
<li><a href = "http://nguyenhuy.github.io/froggy-asdk-layout/">ASStackLayout Game</a>
|
||||
<li><a href = "https://demos.scotch.io/visual-guide-to-css3-flexbox-flexbox-playground/demos/">Visual Guide to CSS3 Flexbox</a>
|
||||
<li><a href = "http://www.flexboxpatterns.com/home">FlexBox Patterns</a>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user