--- title: Upgrading to Layout 2.0 (Beta) layout: docs permalink: /docs/layout2-conversion-guide.html --- A list of the changes: - Introduction of true flex factors - `ASStackLayoutSpec` `.alignItems` property default changed to `ASStackLayoutAlignItemsStretch` - Rename `ASStaticLayoutSpec` to `ASAbsoluteLayoutSpec` - Rename `ASLayoutable` to `ASLayoutElement` - Set `ASLayoutElement` properties via `style` property - Easier way to size of an `ASLayoutElement` - Deprecation of `-[ASDisplayNode preferredFrameSize]` - Deprecation of `-[ASLayoutElement measureWithSizeRange:]` - Deprecation of `-[ASDisplayNode measure:]` - Removal of `-[ASAbsoluteLayoutElement sizeRange]` - Rename `ASRelativeDimension` to `ASDimension` - Introduction of `ASDimensionUnitAuto` In addition to the inline examples comparing **1.x** layout code vs **2.0** layout code, the [example projects](https://github.com/texturegroup/texture/tree/master/examples) and layout documentation have been updated to use the new API. All other **2.0** changes not related to the Layout API are documented here. ## Introduction of true flex factors With **1.x** the `flexGrow` and `flexShrink` properties were of type `BOOL`. With **2.0**, these properties are now type `CGFloat` with default values of `0.0`. This behavior is consistent with the Flexbox implementation for web. See [`flexGrow`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) and [`flexShrink`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink) for further information.
id<ASLayoutElement> layoutElement = ...;
// 1.x:
layoutElement.flexGrow = YES;
layoutElement.flexShrink = YES;
// 2.0:
layoutElement.style.flexGrow = 1.0;
layoutElement.style.flexShrink = 1.0;
// 1.x:
ASStaticLayoutSpec *layoutSpec = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[...]];
// 2.0:
ASAbsoluteLayoutSpec *layoutSpec = [ASAbsoluteLayoutSpec absoluteLayoutSpecWithChildren:@[...]];
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
_photoNode.preferredFrameSize = CGSizeMake(USER_IMAGE_HEIGHT*2, USER_IMAGE_HEIGHT*2);
ASStaticLayoutSpec *backgroundImageStaticSpec = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[_photoNode]];
UIEdgeInsets insets = UIEdgeInsetsMake(INFINITY, 12, 12, 12);
ASInsetLayoutSpec *textInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:_titleNode];
ASOverlayLayoutSpec *textOverlaySpec = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:backgroundImageStaticSpec
overlay:textInsetSpec];
return textOverlaySpec;
}
id<ASLayoutElement> *layoutElement = ...;
// 1.x:
layoutElement.spacingBefore = 1.0;
// 2.0:
layoutElement.style.spacingBefore = 1.0;
// 1.x and 2.0
ASStackLayoutSpec *stackLayoutSpec = ...;
stackLayoutSpec.direction = ASStackLayoutDirectionVertical;
stackLayoutSpec.justifyContent = ASStackLayoutJustifyContentStart;
// 1.x:
// no good way to set an intrinsic size
// 2.0:
ASDisplayNode *ASDisplayNode = ...;
// width 100 points, height: auto
displayNode.style.width = ASDimensionMakeWithPoints(100);
// width 50%, height: auto
displayNode.style.width = ASDimensionMakeWithFraction(0.5);
ASLayoutSpec *layoutSpec = ...;
// width 100 points, height 100 points
layoutSpec.style.preferredSize = CGSizeMake(100, 100);
ASStackLayoutSpec *stackLayoutSpec = ...;
id<ASLayoutElement> *layoutElement = ...;
// 1.x:
layoutElement.sizeRange = ASRelativeSizeRangeMakeWithExactCGSize(CGSizeMake(50, 50));
ASStaticLayoutSpec *staticLayoutSpec = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[layoutElement]];
stackLayoutSpec.children = @[staticLayoutSpec];
// 2.0:
layoutElement.style.preferredSizeRange = ASRelativeSizeRangeMakeWithExactCGSize(CGSizeMake(50, 50));
stackLayoutSpec.children = @[layoutElement];
// 1.x - ASStaticLayoutSpec used as a "wrapper" to return subnode from layoutSpecThatFits:
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[subnode]];
}
// 2.0
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
return [ASWrapperLayoutSpec wrapperWithLayoutElement:subnode];
}
// 1.x - ASStaticLayoutSpec used to set size (but not position) of subnode
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASDisplayNode *subnode = ...;
subnode.preferredSize = ...;
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[subnode]];
}
// 2.0
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASDisplayNode *subnode = ...;
subnode.style.preferredSize = CGSizeMake(constrainedSize.max.width, constrainedSize.max.height / 2.0);
return [ASWrapperLayoutSpec wrapperWithLayoutElement:subnode];
}
ASDisplayNode *ASDisplayNode = ...;
// 1.x:
displayNode.preferredFrameSize = CGSize(100, 100);
// 2.0
displayNode.style.preferredSize = CGSize(100, 100);
// 1.x:
ASLayout *layout = [layoutElement measureWithSizeRange:someSizeRange];
// 2.0:
ASLayout *layout = [layoutElement layoutThatFits:someSizeRange];
// 1.x:
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize {}
// 2.0:
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize {}
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
restrictedToSize:(ASLayoutElementSize)size
relativeToParentSize:(CGSize)parentSize;
- (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize
parentSize:(CGSize)parentSize;
// 1.x:
CGSize size = [displayNode measure:CGSizeMake(100, 100)];
// 2.0:
// Creates an ASSizeRange with min and max sizes.
ASLayout *layout = [displayNode layoutThatFits:ASSizeRangeMake(CGSizeZero, CGSizeMake(100, 100))];
// Or an exact size
// ASLayout *layout = [displayNode layoutThatFits:ASSizeRangeMake(CGSizeMake(100, 100))];
CGSize size = layout.size;
id<ASLayoutElement> layoutElement = ...;
// 1.x:
layoutElement.sizeRange = ASRelativeSizeRangeMakeWithExactCGSize(CGSizeMake(50, 50));
// 2.0:
layoutElement.style.preferredSizeRange = ASRelativeSizeRangeMakeWithExactCGSize(CGSizeMake(50, 50));
// 2.0:
// Handy functions to create ASDimensions
ASDimension dimensionInPoints;
dimensionInPoints = ASDimensionMake(ASDimensionTypePoints, 5.0)
dimensionInPoints = ASDimensionMake(5.0)
dimensionInPoints = ASDimensionMakeWithPoints(5.0)
dimensionInPoints = ASDimensionMake("5.0pt");
ASDimension dimensionInFractions;
dimensionInFractions = ASDimensionMake(ASDimensionTypeFraction, 0.5)
dimensionInFractions = ASDimensionMakeWithFraction(0.5)
dimensionInFractions = ASDimensionMake("50%");
// 2.0:
// No specific size needs to be set as the imageNode's size
// will be calculated from the content (the image in this case)
ASImageNode *imageNode = [ASImageNode new];
imageNode.image = ...;
// Specific size must be set for ASLayoutElement objects that
// do not have an intrinsic content size (ASVideoNode does not
// have a size until it's video downloads)
ASVideoNode *videoNode = [ASVideoNode new];
videoNode.style.preferredSize = CGSizeMake(200, 100);