Latest 0.2
License MIT
Platforms ios 8.0
Dependencies AsyncDisplayKit

ASDKFluentExtensions are a set of Objective-C categories that extend AsyncDisplayKit with a fluent interface for layout code. This fluent style is more visual, improves readability (less visual scanning to grasp layout structure), and makes layout more concise and easier to maintain. It also enables composition of layout specs and styling.

With ASDKFluentExtensions you can write layout code like this:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return image.withOverlay(gradient)

A more complex example in Swift:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return image
        .withRelativePosition(horizontal: .end, vertical: .end)
        .withInset(UIEdgeInsetsMake(.infinity, .infinity, 4, 4))))

Same as before, this time in Objective-C:

- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
  return [[image
              withRelativePositionHorizontal:ASRelativeLayoutSpecPositionEnd vertical:ASRelativeLayoutSpecPositionEnd]
              withInset:UIEdgeInsetsMake(INFINITY, INFINITY, 4, 4)]]]

Composition of layout specs and styling:

- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
  return [[ASStackLayoutSpec horizontalStackLayoutSpec]
          withChildren:@[[avatar withPreferredSize:avatarSize],
                         [name withFlexGrow:1]]];

Another composition example, this time in Swift:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
  return image
      .withRelativePosition(horizontal: .end, vertical: .center)

There is also a category of ASLayoutSpec to create spacers:

let header = ASStackLayoutSpec.withChildren([userName, ASLayoutSpec.spacer(), lastTimeOnline])


ASDKFluentExtensions are syntactic sugar, they don’t add any additional logic to AsyncDisplayKit.

ASDKFluentExtensions are just a bunch of Objective-C categories over ASDisplayNode, ASLayoutSpec, and ASStackLayoutSpec that create and return the desired layout spec passing self as child:

- (ASOverlayLayoutSpec *)withOverlay:(id<ASLayoutElement>)overlay
  return [ASOverlayLayoutSpec overlayLayoutSpecWithChild:self overlay:overlay];

ASDKFluentExtensions also offer categories to modify style properties of the ASDisplayNode or ASLayoutSpec returning self:

- (instancetype)withPreferredSize:(CGSize)preferredSize
{ = preferredSize;
    return self;

This makes layout and styling composable, and enables a very readable fluent API.

Code Duplication and Swift Protocol Extensions

There is a lot of code duplication in order to provide the same functionality for both ASDisplayNode and ASLayoutSpec.

This could be avoided in Swift using protocol extensions over ASLayoutElement, but then the API won’t be available from Objective-C. On the other hand, AsyncDisplayKit is a pure Objective-C framework, so extending it in Swift would introduce limitations. Check here the original Swift implementation of ASDKFluentExtensions, very early abandoned in favor of the current Objective-C API.


You can install ASDKFluentExtensions using CocoaPods. Add the pod to your Podfile:

target 'MyApp' do
  pod "ASDKFluentExtensions"

Then run the following command:

$ pod install

Make sure to import the header:

#import <ASDKFluentExtensions/ASDKFluentExtensions.h>


This is a work in progress. Check this issue on AsyncDisplayKit repo for more info.

More updates soon!


  • Remove code duplication.
  • Tests.
  • Docs.
  • Support Carthage.

Latest podspec

    "name": "ASDKFluentExtensions",
    "version": "0.2",
    "license": {
        "type": "MIT"
    "homepage": "",
    "authors": {
        "Cesar Estebanez": "[email protected]"
    "summary": "Extend AsyncDisplayKit with a fluent layout API",
    "source": {
        "git": "",
        "tag": "0.2"
    "platforms": {
        "ios": "8.0"
    "public_header_files": "Source/*.h",
    "source_files": "Source/*.{h,m}",
    "dependencies": {
        "AsyncDisplayKit": [
            "~> 2.2"

Pin It on Pinterest

Share This