ASDisplayNode Class Reference

Inherits from ASDealloc2MainObject
Conforms to ASLayoutElement
Declared in ASDisplayNode.h

Overview

An ASDisplayNode is an abstraction over UIView and CALayer that allows you to perform calculations about a view hierarchy off the main thread, and could do rendering off the main thread as well.

The node API is designed to be as similar as possible to UIView. See the README for examples.

Subclassing

ASDisplayNode can be subclassed to create a new UI element. The subclass header ASDisplayNode+Subclasses provides necessary declarations and conveniences.

Commons reasons to subclass includes making a UIView property available and receiving a callback after async display.

Initializing a node object

– init

Designated initializer.

- (instancetype)init

Return Value

An ASDisplayNode instance whose view will be a subclass that enables asynchronous rendering, and passes through -layout and touch handling methods.

Declared In

ASDisplayNode.h

– initWithViewBlock:

Alternative initializer with a block to create the backing view.

- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock

Parameters

viewBlock

The block that will be used to create the backing view.

Return Value

An ASDisplayNode instance that loads its view with the given block that is guaranteed to run on the main queue. The view will render synchronously and -layout and touch handling methods on the node will not be called.

Declared In

ASDisplayNode.h

– initWithViewBlock:didLoadBlock:

Alternative initializer with a block to create the backing view.

- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock didLoadBlock:(nullable ASDisplayNodeDidLoadBlock)didLoadBlock

Parameters

viewBlock

The block that will be used to create the backing view.

didLoadBlock

The block that will be called after the view created by the viewBlock is loaded

Return Value

An ASDisplayNode instance that loads its view with the given block that is guaranteed to run on the main queue. The view will render synchronously and -layout and touch handling methods on the node will not be called.

Declared In

ASDisplayNode.h

– initWithLayerBlock:

Alternative initializer with a block to create the backing layer.

- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock

Parameters

layerBlock

The block that will be used to create the backing layer.

Return Value

An ASDisplayNode instance that loads its layer with the given block that is guaranteed to run on the main queue. The layer will render synchronously and -layout and touch handling methods on the node will not be called.

Declared In

ASDisplayNode.h

– initWithLayerBlock:didLoadBlock:

Alternative initializer with a block to create the backing layer.

- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock didLoadBlock:(nullable ASDisplayNodeDidLoadBlock)didLoadBlock

Parameters

layerBlock

The block that will be used to create the backing layer.

didLoadBlock

The block that will be called after the layer created by the layerBlock is loaded

Return Value

An ASDisplayNode instance that loads its layer with the given block that is guaranteed to run on the main queue. The layer will render synchronously and -layout and touch handling methods on the node will not be called.

Declared In

ASDisplayNode.h

– onDidLoad:

Add a block of work to be performed on the main thread when the node’s view or layer is loaded. Thread safe.

- (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body

Parameters

body

The work to be performed when the node is loaded.

@precondition The node is not already loaded.

Discussion

Warning: Be careful not to retain self in body. Change the block parameter list to ^(MYCustomNode *self) {} if you want to shadow self (e.g. if calling this during init).

Note: This will only be called the next time the node is loaded. If the node is later added to a subtree of a node that has shouldRasterizeDescendants=YES, and is unloaded, this block will not be called if it is loaded again.

Declared In

ASDisplayNode.h

  synchronous

Returns whether the node is synchronous.

@property (nonatomic, readonly, assign, getter=isSynchronous) BOOL synchronous

Return Value

NO if the node wraps a _ASDisplayView, YES otherwise.

Declared In

ASDisplayNode.h

Getting view and layer

  view

Returns a view.

@property (nonatomic, readonly, strong) UIView *view

Discussion

The view property is lazily initialized, similar to UIViewController. To go the other direction, use ASViewToDisplayNode() in ASDisplayNodeExtras.h.

Warning: The first access to it must be on the main thread, and should only be used on the main thread thereafter as well.

Declared In

ASDisplayNode.h

  nodeLoaded

Returns whether a node’s backing view or layer is loaded.

@property (nonatomic, readonly, assign, getter=isNodeLoaded) BOOL nodeLoaded

Return Value

YES if a view is loaded, or if layerBacked is YES and layer is not nil; NO otherwise.

Declared In

ASDisplayNode.h

  layerBacked

Returns whether the node rely on a layer instead of a view.

@property (nonatomic, assign, getter=isLayerBacked) BOOL layerBacked

Return Value

YES if the node rely on a layer, NO otherwise.

Declared In

ASDisplayNode.h

  layer

Returns a layer.

@property (nonatomic, readonly, strong) CALayer *layer

Discussion

The layer property is lazily initialized, similar to the view property. To go the other direction, use ASLayerToDisplayNode() in ASDisplayNodeExtras.h.

Warning: The first access to it must be on the main thread, and should only be used on the main thread thereafter as well.

Declared In

ASDisplayNode.h

  visible

Returns YES if the node is – at least partially – visible in a window.

@property (readonly, getter=isVisible) BOOL visible

Declared In

ASDisplayNode.h

  inPreloadState

Returns YES if the node is in the preloading interface state.

@property (readonly, getter=isInPreloadState) BOOL inPreloadState

Declared In

ASDisplayNode.h

  inDisplayState

Returns YES if the node is in the displaying interface state.

@property (readonly, getter=isInDisplayState) BOOL inDisplayState

Declared In

ASDisplayNode.h

  interfaceState

Returns the Interface State of the node.

@property (readonly) ASInterfaceState interfaceState

Return Value

The current ASInterfaceState of the node, indicating whether it is visible and other situational properties.

See Also

Declared In

ASDisplayNode.h

Managing dimensions

– layoutThatFits:

Asks the node to return a layout based on given size range.

- (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize

Parameters

constrainedSize

The minimum and maximum sizes the receiver should fit in.

Return Value

An ASLayout instance defining the layout of the receiver (and its children, if the box layout model is used).

Discussion

Though this method does not set the bounds of the view, it does have side effects–caching both the constraint and the result.

Warning: Subclasses must not override this; it caches results from -calculateLayoutThatFits:. Calling this method may be expensive if result is not cached.

Declared In

ASDisplayNode.h

  layoutSpecBlock

Provides a way to declare a block to provide an ASLayoutSpec without having to subclass ASDisplayNode and implement layoutSpecThatFits:

@property (nonatomic, readwrite, copy, nullable) ASLayoutSpecBlock layoutSpecBlock

Return Value

A block that takes a constrainedSize ASSizeRange argument, and must return an ASLayoutSpec that includes all of the subnodes to position in the layout. This input-output relationship is identical to the subclass override method -layoutSpecThatFits:

Discussion

Warning: Subclasses that implement -layoutSpecThatFits: must not also use .layoutSpecBlock. Doing so will trigger an exception. A future version of the framework may support using both, calling them serially, with the .layoutSpecBlock superseding any values set by the method override.

Declared In

ASDisplayNode.h

  calculatedSize

Return the calculated size.

@property (nonatomic, readonly, assign) CGSize calculatedSize

Return Value

Size already calculated by -calculateLayoutThatFits:.

Discussion

Ideal for use by subclasses in -layout, having already prompted their subnodes to calculate their size by calling -measure: on them in -calculateLayoutThatFits.

Warning: Subclasses must not override this; it returns the last cached measurement and is never expensive.

Declared In

ASDisplayNode.h

  constrainedSizeForCalculatedLayout

Return the constrained size range used for calculating layout.

@property (nonatomic, readonly, assign) ASSizeRange constrainedSizeForCalculatedLayout

Return Value

The minimum and maximum constrained sizes used by calculateLayoutThatFits:.

Declared In

ASDisplayNode.h

Managing the nodes hierarchy

– addSubnode:

Add a node as a subnode to this node.

- (void)addSubnode:(ASDisplayNode *)subnode

Parameters

subnode

The node to be added.

Discussion

The subnode’s view will automatically be added to this node’s view, lazily if the views are not created yet.

Declared In

ASDisplayNode.h

– insertSubnode:belowSubnode:

Insert a subnode before a given subnode in the list.

- (void)insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below

Parameters

subnode

The node to insert below another node.

below

The sibling node that will be above the inserted node.

Discussion

If the views are loaded, the subnode’s view will be inserted below the given node’s view in the hierarchy even if there are other non-displaynode views.

Declared In

ASDisplayNode.h

– insertSubnode:aboveSubnode:

Insert a subnode after a given subnode in the list.

- (void)insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above

Parameters

subnode

The node to insert below another node.

above

The sibling node that will be behind the inserted node.

Discussion

If the views are loaded, the subnode’s view will be inserted above the given node’s view in the hierarchy even if there are other non-displaynode views.

Declared In

ASDisplayNode.h

– insertSubnode:atIndex:

Insert a subnode at a given index in subnodes.

- (void)insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx

Parameters

subnode

The node to insert.

idx

The index in the array of the subnodes property at which to insert the node. Subnodes indices start at 0 and cannot be greater than the number of subnodes.

Discussion

If this node’s view is loaded, ASDisplayNode insert the subnode’s view after the subnode at index - 1’s view even if there are other non-displaynode views.

Declared In

ASDisplayNode.h

– replaceSubnode:withSubnode:

Replace subnode with replacementSubnode.

- (void)replaceSubnode:(ASDisplayNode *)subnode withSubnode:(ASDisplayNode *)replacementSubnode

Parameters

subnode

A subnode of self.

replacementSubnode

A node with which to replace subnode.

Discussion

Should both subnode and replacementSubnode already be subnodes of self, subnode is removed and replacementSubnode inserted in its place. If subnode is not a subnode of self, this method will throw an exception. If replacementSubnode is nil, this method will throw an exception

Declared In

ASDisplayNode.h

– removeFromSupernode

Remove this node from its supernode.

- (void)removeFromSupernode

Discussion

The node’s view will be automatically removed from the supernode’s view.

Declared In

ASDisplayNode.h

  subnodes

The receiver’s immediate subnodes.

@property (nonatomic, readonly, copy) NSArray<ASDisplayNode*> *subnodes

Declared In

ASDisplayNode.h

  supernode

The receiver’s supernode.

@property (nonatomic, readonly, weak) ASDisplayNode *supernode

Declared In

ASDisplayNode.h

Drawing and Updating the View

  displaysAsynchronously

Whether this node’s view performs asynchronous rendering.

@property (nonatomic, assign) BOOL displaysAsynchronously

Return Value

Defaults to YES, except for synchronous views (ie, those created with -initWithViewBlock: / -initWithLayerBlock:), which are always NO.

Discussion

If this flag is set, then the node will participate in the current asyncdisplaykit_async_transaction and do its rendering on the displayQueue instead of the main thread.

Asynchronous rendering proceeds as follows:

When the view is initially added to the hierarchy, it has -needsDisplay true. After layout, Core Animation will call -display on the _ASDisplayLayer -display enqueues a rendering operation on the displayQueue When the render block executes, it calls the delegate display method (-drawRect:… or -display) The delegate provides contents via this method and an operation is added to the asyncdisplaykit_async_transaction Once all rendering is complete for the current asyncdisplaykit_async_transaction, the completion for the block sets the contents on all of the layers in the same frame

If asynchronous rendering is disabled:

When the view is initially added to the hierarchy, it has -needsDisplay true. After layout, Core Animation will call -display on the _ASDisplayLayer -display calls delegate display method (-drawRect:… or -display) immediately -display sets the layer contents immediately with the result

Note: this has nothing to do with -[CALayer drawsAsynchronously].

Declared In

ASDisplayNode.h

  shouldRasterizeDescendants

Whether to draw all descendant nodes' layers/views into this node’s layer/view’s backing store.

@property (nonatomic, assign) BOOL shouldRasterizeDescendants

Declared In

ASDisplayNode.h

  displaySuspended

Prevent the node’s layer from displaying.

@property (nonatomic, assign) BOOL displaySuspended

Discussion

A subclass may check this flag during -display or -drawInContext: to cancel a display that is already in progress.

Defaults to NO. Does not control display for any child or descendant nodes; for that, use -recursivelySetDisplaySuspended:.

If a setNeedsDisplay occurs while displaySuspended is YES, and displaySuspended is set to NO, then the layer will be automatically displayed.

Declared In

ASDisplayNode.h

  shouldAnimateSizeChanges

Whether size changes should be animated. Default to YES.

@property (nonatomic, assign) BOOL shouldAnimateSizeChanges

Declared In

ASDisplayNode.h

– recursivelySetDisplaySuspended:

Prevent the node and its descendants' layer from displaying.

- (void)recursivelySetDisplaySuspended:(BOOL)flag

Parameters

flag

YES if display should be prevented or cancelled; NO otherwise.

Declared In

ASDisplayNode.h

– recursivelyClearContents

Calls -clearContents on the receiver and its subnode hierarchy.

- (void)recursivelyClearContents

Discussion

Clears backing stores and other memory-intensive intermediates. If the node is removed from a visible hierarchy and then re-added, it will automatically trigger a new asynchronous display, as long as displaySuspended is not set. If the node remains in the hierarchy throughout, -setNeedsDisplay is required to trigger a new asynchronous display.

See Also

Declared In

ASDisplayNode.h

– recursivelyClearFetchedData

Calls -clearFetchedData on the receiver and its subnode hierarchy.

- (void)recursivelyClearFetchedData

Discussion

Clears any memory-intensive fetched content. This method is used to notify the node that it should purge any content that is both expensive to fetch and to retain in memory.

Declared In

ASDisplayNode.h

– recursivelyFetchData

Calls -fetchData on the receiver and its subnode hierarchy.

- (void)recursivelyFetchData

Discussion

Fetches content from remote sources for the current node and all subnodes.

Declared In

ASDisplayNode.h

– setNeedsDataFetch

Triggers a recursive call to fetchData when the node has an interfaceState of ASInterfaceStatePreload

- (void)setNeedsDataFetch

Declared In

ASDisplayNode.h

  placeholderEnabled

Toggle displaying a placeholder over the node that covers content until the node and all subnodes are displayed.

@property (nonatomic, assign) BOOL placeholderEnabled

Discussion

Defaults to NO.

Declared In

ASDisplayNode.h

  placeholderFadeDuration

Set the time it takes to fade out the placeholder when a node’s contents are finished displaying.

@property (nonatomic, assign) NSTimeInterval placeholderFadeDuration

Discussion

Defaults to 0 seconds.

Declared In

ASDisplayNode.h

  drawingPriority

Determines drawing priority of the node. Nodes with higher priority will be drawn earlier.

@property (nonatomic, assign) NSInteger drawingPriority

Discussion

Defaults to ASDefaultDrawingPriority. There may be multiple drawing threads, and some of them may decide to perform operations in queued order (regardless of drawingPriority)

Declared In

ASDisplayNode.h

Hit Testing

  hitTestSlop

Bounds insets for hit testing.

@property (nonatomic, assign) UIEdgeInsets hitTestSlop

Discussion

When set to a non-zero inset, increases the bounds for hit testing to make it easier to tap or perform gestures on this node. Default is UIEdgeInsetsZero.

This affects the default implementation of -hitTest and -pointInside, so subclasses should call super if you override it and want hitTestSlop applied.

Declared In

ASDisplayNode.h

– pointInside:withEvent:

Returns a Boolean value indicating whether the receiver contains the specified point.

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event

Parameters

point

A point that is in the receiver’s local coordinate system (bounds).

event

The event that warranted a call to this method.

Return Value

YES if point is inside the receiver’s bounds; otherwise, NO.

Discussion

Includes the “slop” factor specified with hitTestSlop.

Declared In

ASDisplayNode.h

Converting Between View Coordinate Systems

– convertPoint:toNode:

Converts a point from the receiver’s coordinate system to that of the specified node.

- (CGPoint)convertPoint:(CGPoint)point toNode:(nullable ASDisplayNode *)node

Parameters

point

A point specified in the local coordinate system (bounds) of the receiver.

node

The node into whose coordinate system point is to be converted.

Return Value

The point converted to the coordinate system of node.

Declared In

ASDisplayNode.h

– convertPoint:fromNode:

Converts a point from the coordinate system of a given node to that of the receiver.

- (CGPoint)convertPoint:(CGPoint)point fromNode:(nullable ASDisplayNode *)node

Parameters

point

A point specified in the local coordinate system (bounds) of node.

node

The node with point in its coordinate system.

Return Value

The point converted to the local coordinate system (bounds) of the receiver.

Declared In

ASDisplayNode.h

– convertRect:toNode:

Converts a rectangle from the receiver’s coordinate system to that of another view.

- (CGRect)convertRect:(CGRect)rect toNode:(nullable ASDisplayNode *)node

Parameters

rect

A rectangle specified in the local coordinate system (bounds) of the receiver.

node

The node that is the target of the conversion operation.

Return Value

The converted rectangle.

Declared In

ASDisplayNode.h

– convertRect:fromNode:

Converts a rectangle from the coordinate system of another node to that of the receiver.

- (CGRect)convertRect:(CGRect)rect fromNode:(nullable ASDisplayNode *)node

Parameters

rect

A rectangle specified in the local coordinate system (bounds) of node.

node

The node with rect in its coordinate system.

Return Value

The converted rectangle.

Declared In

ASDisplayNode.h