diff --git a/404.md b/404.md index 66e29ed3..259ecac4 100755 --- a/404.md +++ b/404.md @@ -6,6 +6,6 @@ layout: default # Page Not Found -Monkeys! There exists no such page. +Crikey! There doesn't seem to be anything here. -If you find a link to be broken, feel free to send a pull request. You can also let us know at [@componentkit](https://www.twitter.com/componentkit) so that we can fix it. +If you find a broken link, feel free to send a pull request. You can also let us know at [Github](https://github.com/facebook/AsyncDisplayKit/issues) so that we can fix it. diff --git a/_data/nav_docs.yml b/_data/nav_docs.yml index b5487c91..c8579a26 100755 --- a/_data/nav_docs.yml +++ b/_data/nav_docs.yml @@ -1,5 +1,7 @@ - title: Quick Start items: + - philosophy + - installation - getting-started - title: Core Concepts items: @@ -28,15 +30,11 @@ - scroll-node - title: Layout Engine items: - - layout-basics - - layout-spec - - stack-layout-spec - - inset-layout-spec - - background-layout-spec - - center-layout-spec - - overlay-layout-spec - - relative-layout-spec - - static-layout-spec + - layout-options + - automatic-layout-basics + - automatic-layout-containers + - automatic-layout-examples + - automatic-layout-debugging - title: Optimizations items: - layer-backing diff --git a/_docs/layout-basics.md b/_docs/automatic-layout-basics.md similarity index 67% rename from _docs/layout-basics.md rename to _docs/automatic-layout-basics.md index eb712036..9170aaf8 100644 --- a/_docs/layout-basics.md +++ b/_docs/automatic-layout-basics.md @@ -1,7 +1,7 @@ --- -title: Layout Basics +title: Automatic Layout Basics layout: docs -permalink: /docs/layout-basics.html +permalink: /docs/automatic-layout-basics.html --- ##Box Model Layout @@ -28,31 +28,7 @@ Every ASLayoutSpec must act on at least one child. The ASLayoutSpec has the resp You don’t need to be aware of **`ASLayout`** except to know that it represents a computed immutable layout tree and is returned by objects conforming to the `` protocol. -##Layout Containers - -AsyncDisplayKit includes a library of components that can be composed to declaratively specify a layout. The following LayoutSpecs allow you to have multiple children: - -* **ASStackLayoutSpec** is based on a simplified version of CSS flexbox. It allows you to stack components vertically or horizontally and specify how they should be flexed and aligned to fit in the available space. -* **ASStaticLayoutSpec** allows positioning children at fixed offsets. - -The following layoutSpecs allow you to layout a single children: - -* **ASLayoutSpec** can be used as a spacer if it contains no children -* **ASInsetLayoutSpec** applies an inset margin around a component. -* **ASBackgroundLayoutSpec** lays out a component, stretching another component behind it as a backdrop. -* **ASOverlayLayoutSpec** lays out a component, stretching another component on top of it as an overlay. -* **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. - -##Implementing layoutSpecThatFits: - -##Strategy - ##Layout for UIKit Components: - for UIViews that are added directly, you will still need to manually lay it out in `didLoad:` - for UIViews that are added ASDisplay initWithViewBlock, you can then include it in `layoutSpecThatFits:` -##Debugging with ASCII Art - -##Legacy Layout Methods diff --git a/_docs/automatic-layout-containers.md b/_docs/automatic-layout-containers.md new file mode 100644 index 00000000..99d4bb3b --- /dev/null +++ b/_docs/automatic-layout-containers.md @@ -0,0 +1,23 @@ +--- +title: Automatic Layout Containers +layout: docs +permalink: /docs/automatic-layout-containers.html +--- + +AsyncDisplayKit includes a library of components that can be composed to declaratively specify a layout. The following LayoutSpecs allow you to have multiple children: + +* **ASStackLayoutSpec** is based on a simplified version of CSS flexbox. It allows you to stack components vertically or horizontally and specify how they should be flexed and aligned to fit in the available space. +* **ASStaticLayoutSpec** allows positioning children at fixed offsets. + +The following layoutSpecs allow you to layout a single children: + +* **ASLayoutSpec** can be used as a spacer if it contains no children +* **ASInsetLayoutSpec** applies an inset margin around a component. +* **ASBackgroundLayoutSpec** lays out a component, stretching another component behind it as a backdrop. +* **ASOverlayLayoutSpec** lays out a component, stretching another component on top of it as an overlay. +* **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 diff --git a/_docs/automatic-layout-debugging.md b/_docs/automatic-layout-debugging.md new file mode 100755 index 00000000..a43b8e1d --- /dev/null +++ b/_docs/automatic-layout-debugging.md @@ -0,0 +1,9 @@ +--- +title: Automatic Layout Debugging +layout: docs +permalink: /docs/automatic-layout-debugging.html +--- + +##Debugging with ASCII Art + +##ASLayoutSpecPlayground App diff --git a/_docs/automatic-layout-examples.md b/_docs/automatic-layout-examples.md new file mode 100755 index 00000000..e686f004 --- /dev/null +++ b/_docs/automatic-layout-examples.md @@ -0,0 +1,175 @@ +--- +title: Automatic Layout Examples +layout: docs +permalink: /docs/automatic-layout-examples.html +--- +Three examples in increasing order of complexity. +#NSSpain Talk Example + + + +```objective-c + +- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constraint +{ + ASStackLayoutSpec *vStack = [[ASStackLayoutSpec alloc] init]; + + [vStack setChildren:@[titleNode, bodyNode]; + + ASStackLayoutSpec *hstack = [[ASStackLayoutSpec alloc] init]; + hStack.direction = ASStackLayoutDirectionHorizontal; + hStack.spacing = 5.0; + + [hStack setChildren:@[imageNode, vStack]]; + + ASInsetLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(5,5,5,5) child:hStack]; + + return insetSpec; +} +``` + +###Discussion + +#Social App Layout + + + +```objective-c +- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize +{ + // header stack + _userAvatarImageView.preferredFrameSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT); // constrain avatar image frame size + + ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init]; + spacer.flexGrow = YES; + + ASStackLayoutSpec *headerStack = [ASStackLayoutSpec horizontalStackLayoutSpec]; + headerStack.alignItems = ASStackLayoutAlignItemsCenter; // center items vertically in horizontal stack + headerStack.justifyContent = ASStackLayoutJustifyContentStart; // justify content to left side of header stack + headerStack.spacing = HORIZONTAL_BUFFER; + + [headerStack setChildren:@[_userAvatarImageView, _userNameLabel, spacer, _photoTimeIntervalSincePostLabel]]; + + // header inset stack + + UIEdgeInsets insets = UIEdgeInsetsMake(0, HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER); + ASInsetLayoutSpec *headerWithInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:headerStack]; + headerWithInset.flexShrink = YES; + + // 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; +} + +``` + +###Discussion + +Get the full ASDK project at examples/ASDKgram. + +#Social App Layout 2 + + + +```objective-c +- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { + + ASLayoutSpec *textSpec = [self textSpec]; + ASLayoutSpec *imageSpec = [self imageSpecWithSize:constrainedSize]; + ASOverlayLayoutSpec *soldOutOverImage = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:imageSpec + overlay:[self soldOutLabelSpec]]; + + NSArray *stackChildren = @[soldOutOverImage, textSpec]; + + ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical + spacing:0.0 + justifyContent:ASStackLayoutJustifyContentStart + alignItems:ASStackLayoutAlignItemsStretch + children:stackChildren]; + + ASOverlayLayoutSpec *soldOutOverlay = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:mainStack + overlay:self.soldOutOverlay]; + + return soldOutOverlay; +} + +- (ASLayoutSpec *)textSpec { + CGFloat kInsetHorizontal = 16.0; + CGFloat kInsetTop = 6.0; + CGFloat kInsetBottom = 0.0; + UIEdgeInsets textInsets = UIEdgeInsetsMake(kInsetTop, kInsetHorizontal, kInsetBottom, kInsetHorizontal); + + ASLayoutSpec *verticalSpacer = [[ASLayoutSpec alloc] init]; + verticalSpacer.flexGrow = YES; + + ASLayoutSpec *horizontalSpacer1 = [[ASLayoutSpec alloc] init]; + horizontalSpacer1.flexGrow = YES; + + ASLayoutSpec *horizontalSpacer2 = [[ASLayoutSpec alloc] init]; + horizontalSpacer2.flexGrow = YES; + + NSArray *info1Children = @[self.firstInfoLabel, self.distanceLabel, horizontalSpacer1, self.originalPriceLabel]; + NSArray *info2Children = @[self.secondInfoLabel, horizontalSpacer2, self.finalPriceLabel]; + if ([ItemNode isRTL]) { + info1Children = [[info1Children reverseObjectEnumerator] allObjects]; + info2Children = [[info2Children reverseObjectEnumerator] allObjects]; + } + + ASStackLayoutSpec *info1Stack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal + spacing:1.0 + justifyContent:ASStackLayoutJustifyContentStart + alignItems:ASStackLayoutAlignItemsBaselineLast children:info1Children]; + + ASStackLayoutSpec *info2Stack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal + spacing:0.0 + justifyContent:ASStackLayoutJustifyContentCenter + alignItems:ASStackLayoutAlignItemsBaselineLast children:info2Children]; + + ASStackLayoutSpec *textStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical + spacing:0.0 + justifyContent:ASStackLayoutJustifyContentEnd + alignItems:ASStackLayoutAlignItemsStretch + children:@[self.titleLabel, verticalSpacer, info1Stack, info2Stack]]; + + ASInsetLayoutSpec *textWrapper = [ASInsetLayoutSpec insetLayoutSpecWithInsets:textInsets + child:textStack]; + textWrapper.flexGrow = YES; + + return textWrapper; +} + +- (ASLayoutSpec *)imageSpecWithSize:(ASSizeRange)constrainedSize { + CGFloat imageRatio = [self imageRatioFromSize:constrainedSize.max]; + + ASRatioLayoutSpec *imagePlace = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:imageRatio child:self.dealImageView]; + + self.badge.layoutPosition = CGPointMake(0, constrainedSize.max.height - kFixedLabelsAreaHeight - kBadgeHeight); + self.badge.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMake(ASRelativeDimensionMakeWithPercent(0), ASRelativeDimensionMakeWithPoints(kBadgeHeight)), ASRelativeSizeMake(ASRelativeDimensionMakeWithPercent(1), ASRelativeDimensionMakeWithPoints(kBadgeHeight))); + ASStaticLayoutSpec *badgePosition = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[self.badge]]; + + ASOverlayLayoutSpec *badgeOverImage = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:imagePlace overlay:badgePosition]; + badgeOverImage.flexGrow = YES; + + return badgeOverImage; +} + +- (ASLayoutSpec *)soldOutLabelSpec { + ASCenterLayoutSpec *centerSoldOutLabel = [ASCenterLayoutSpec centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY + sizingOptions:ASCenterLayoutSpecSizingOptionMinimumXY child:self.soldOutLabelFlat]; + ASStaticLayoutSpec *soldOutBG = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[self.soldOutLabelBackground]]; + ASCenterLayoutSpec *centerSoldOut = [ASCenterLayoutSpec centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY sizingOptions:ASCenterLayoutSpecSizingOptionDefault child:soldOutBG]; + ASBackgroundLayoutSpec *soldOutLabelOverBackground = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:centerSoldOutLabel background:centerSoldOut]; + return soldOutLabelOverBackground; +} +``` + +###Discussion +Get the full ASDK project at examples/CatDealsCollectionView. diff --git a/_docs/center-layout-spec.md b/_docs/center-layout-spec.md deleted file mode 100755 index 3dba3b62..00000000 --- a/_docs/center-layout-spec.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: ASCenterLayoutSpec -layout: docs -permalink: /docs/center-layout-spec.html ---- - diff --git a/_docs/installation.md b/_docs/installation.md new file mode 100644 index 00000000..4e584e4d --- /dev/null +++ b/_docs/installation.md @@ -0,0 +1,35 @@ +--- +title: Installation +layout: docs +permalink: /docs/installation.html +next: quick-start.html +--- + +###CocoaPods + + ASDK is available on CocoaPods. Add the following to your Podfile: + + ```objective-c +pod 'AsyncDisplayKit' +``` + +ASDK 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. + +Import the framework header, or create an Objective-C bridging header if you're using **Swift**: + + ```objective-c +#import +``` + +###Carthage + +ASDK is available through Carthage. 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 Carthage. diff --git a/_docs/layout-options.md b/_docs/layout-options.md new file mode 100644 index 00000000..51aeb844 --- /dev/null +++ b/_docs/layout-options.md @@ -0,0 +1,50 @@ +--- +title: Layout Options +layout: docs +permalink: /docs/layout-options.html +--- + +When using ASDK, you have three options for layout. Note that UIKit Autolayout is **not** supported by ASDK. +#Manual Sizing & Layout + +This original layout method shipped with ASDK 1.0 and is analogous to UIKit's layout methods. Use this method for for ASViewControllers (unless you subclass the node). + +`[ASDisplayNode calculateSizeThatFits:]` **vs.** `[UIView sizeThatFits:]` + +`[ASDisplayNode layout]` **vs.** `[UIView layoutSubviews]` + +###Advantages (over UIKit) +- Eliminates all main thread layout cost +- Results are cached + +###Shortcomings (same as UIKit): +- Code duplication between methods +- Logic is not reusable + +#Unified Sizing & Layout + +This layout method does not have a UIKit analog. It is implemented by calling + +`- (ASLayout *)calculateLayoutThatFits: (ASSizeRange)constraint` + +###Advantages +- zero duplication +- still async, still cached + +###Shortcomings +- logic is not reusable, and is still manual + +# Automatic, Extensible Layout + +This is the reccomended layout method. It does not have a UIKit analog and is implemented by calling + +`- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constraint` +###Advantages +- can reuse even complex, custom layouts +- built-in specs provide automatic layout +- combine to compose new layouts easily +- still async, cached, and zero duplication + +The diagram below shows how options #2 and #3 above both result in an ASLayout, except that in option #3, the ASLayout is produced automatically by the ASLayoutSpec. + + diff --git a/_docs/layout-specs.md b/_docs/layout-specs.md deleted file mode 100644 index 8b510b3b..00000000 --- a/_docs/layout-specs.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Layout Specs -layout: docs -permalink: /docs/layout-specs.html ---- - diff --git a/_docs/philosophy.md b/_docs/philosophy.md new file mode 100644 index 00000000..8db55266 --- /dev/null +++ b/_docs/philosophy.md @@ -0,0 +1,46 @@ +--- +title: Philosophy +layout: docs +permalink: /docs/philosophy.html +next: installation.html +--- + +#Asynchronous Performance Gains + +AsyncDisplayKit is a UI framework that was originally born from Facebook’s Paper app. It came as an answer to one of the core questions the Paper team faced. **How can you keep the main thread as clear as possible?** + +Nowadays, many apps have a user experience that relies heavily upon continuous gestures and physics based animations. At the very least, your UI is probably dependent on some form of scroll view. These types of user interfaces depend entirely on the main thread and are extremely sensitive to main thread stalls. **A clogged main thread means dropped frames and an unpleasant user experience.** + +AsyncDisplayKit Nodes are a thread-safe abstraction layer over UIViews and CALayers: + +logo + +You can access most view and layer properties when using nodes, the difference is that nodes are rendered concurrently by default, and measured and laid out asynchronously when used correctly! + +Too see asynchronous performance gains in action, check out the `examples/ASDKgram` app which compares a UIKit-implemented social media feed with an ASDK-implemented social media feed! + +On an iPhone 6+, the performance may not be radically different, but on a 4S, the difference is dramatic! Which leads us to ASDK's next priority... + +#A Great App Experience for All Users + +ASDK's performance gains allow you to easily design an great experience for every app user - across all devices, on all network connections. + +##A Great Developer Experience + +ASDK also strives to make the developer experience great +- platform compatability: iOS & tvOS +- language compatability: Objective-C & Swift +- requires fewer lines of code to build advanced apps (see `examples/ASDKgram` for a direct comparison of UIKit-implemented app vs. ASDK-implemented app) +- cleaner architecture patterns +- robust code (some really brilliant minds have worked on this for 3+ years) + +#Advanced Developer Tools + +As ASDK has grown, some of the brightest iOS engineers have contributed advanced technologies that will enable you, as a developer using ASDK, to save yourself development time. + +###Advanced Technology +- ASRunLoopQueue +- ASRangeController with Intelligent Preloading + +###Network Code Savings +- automatic batch fetching (e.g. JSON payloads) diff --git a/_docs/stack-layout-spec.md b/_docs/stack-layout-spec.md deleted file mode 100755 index df0e0df5..00000000 --- a/_docs/stack-layout-spec.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: ASStackLayoutSpec -layout: docs -permalink: /docs/stack-layout-spec.html ---- diff --git a/index.md b/index.md index 8b1340b6..2002fba1 100755 --- a/index.md +++ b/index.md @@ -16,33 +16,8 @@ id: home pop's physics-based animations — but it's just as powerful with UIKit Dynamics and conventional app designs.

- As the framework has grown, many features have been added that can save developers tons of time by eliminating common boilerplate style structures common in modern iOS apps. +

As the framework has grown, many features have been added that can save developers tons of time by eliminating common boilerplate style structures common in modern iOS apps. If you've ever dealt with cell reuse bugs, tried to performantly preload data for a page or scroll style interface or even just tried to keep your app from dropping too many frames you can benefit from integrating ASDK.

- If you've ever dealt with cell reuse bugs, tried to performantly preload data for a page or scroll style interface or even just tried to keep your app from dropping too many frames you can benefit from integrating ASDK. - -


- -

Quick start

- -

ASDK is available on CocoaPods. Add the following to your Podfile:

-
pod 'AsyncDisplayKit'
-    
-

(ASDK 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.)

- -

Import the framework header, or create an Objective-C bridging - header - if you're using Swift:

-
#import <AsyncDisplayKit/AsyncDisplayKit.h>
-    
-

AsyncDisplayKit Nodes are a thread-safe abstraction layer over UIViews and - CALayers:

- -

logo

- - You can access most view and layer properties when using nodes, the difference is that nodes are rendered concurrently by default, and measured and laid out asynchronously when used correctly!

To learn more, check out our docs! diff --git a/static/layout-example-1.png b/static/layout-example-1.png new file mode 100644 index 00000000..aac85798 Binary files /dev/null and b/static/layout-example-1.png differ diff --git a/static/layout-example-2.png b/static/layout-example-2.png new file mode 100644 index 00000000..673c1672 Binary files /dev/null and b/static/layout-example-2.png differ diff --git a/static/layout-example-3.png b/static/layout-example-3.png new file mode 100644 index 00000000..72f9179e Binary files /dev/null and b/static/layout-example-3.png differ