diff --git a/CSSLayoutKit/UIView+CSSLayout.h b/CSSLayoutKit/UIView+CSSLayout.h index f08daa94..b7951b83 100644 --- a/CSSLayoutKit/UIView+CSSLayout.h +++ b/CSSLayoutKit/UIView+CSSLayout.h @@ -12,8 +12,10 @@ @interface UIView (CSSLayout) -- (void)css_setUsesFlexbox:(BOOL)enabled; -- (BOOL)css_usesFlexbox; +/** + The property that decides during layout/sizing whether or not css_* properties should be applied. Defaults to NO. + */ +@property (nonatomic, readwrite, assign, setter=css_setUsesFlexbox:) BOOL css_usesFlexbox; - (void)css_setDirection:(CSSDirection)direction; - (void)css_setFlexDirection:(CSSFlexDirection)flexDirection; @@ -39,13 +41,19 @@ - (void)css_setMaxWidth:(CGFloat)maxWidth; - (void)css_setMaxHeight:(CGFloat)maxHeight; -// Get the resolved direction of this node. This won't be CSSDirectionInherit +/** + Get the resolved direction of this node. This won't be CSSDirectionInherit + */ - (CSSDirection)css_resolvedDirection; -//! @abstract Perform a layout calculation and update the frames of the views in the hierarchy with th results +/** + Perform a layout calculation and update the frames of the views in the hierarchy with th results + */ - (void)css_applyLayout; -//! @abstract Compute the size of a layout with a constrained size. +/** + Compute the size of a layout with a constrained size. + */ - (CGSize)css_sizeThatFits:(CGSize)constrainedSize; @end diff --git a/CSSLayoutKit/UIView+CSSLayout.m b/CSSLayoutKit/UIView+CSSLayout.m index 31cfbf1b..645cdd30 100644 --- a/CSSLayoutKit/UIView+CSSLayout.m +++ b/CSSLayoutKit/UIView+CSSLayout.m @@ -33,18 +33,14 @@ @implementation UIView (CSSLayout) -- (CSSNodeRef)cssNode +- (BOOL)css_usesFlexbox { - CSSNodeBridge *node = objc_getAssociatedObject(self, @selector(cssNode)); - if (!node) { - node = [CSSNodeBridge new]; - CSSNodeSetContext(node.cnode, (__bridge void *) self); - objc_setAssociatedObject(self, @selector(cssNode), node, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } - - return node.cnode; + NSNumber *usesFlexbox = objc_getAssociatedObject(self, @selector(css_usesFlexbox)); + return [usesFlexbox boolValue]; } +#pragma mark - Setters + - (void)css_setUsesFlexbox:(BOOL)enabled { objc_setAssociatedObject( @@ -54,12 +50,6 @@ OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (BOOL)css_usesFlexbox -{ - NSNumber *usesFlexbox = objc_getAssociatedObject(self, @selector(css_usesFlexbox)); - return [usesFlexbox boolValue]; -} - - (void)css_setDirection:(CSSDirection)direction { CSSNodeStyleSetDirection([self cssNode], direction); @@ -160,6 +150,8 @@ CSSNodeStyleSetMaxHeight([self cssNode], maxHeight); } +#pragma mark - Layout and Sizing + - (CSSDirection)css_resolvedDirection { return CSSNodeLayoutGetDirection([self cssNode]); @@ -170,7 +162,7 @@ NSAssert([NSThread isMainThread], @"CSS Layout calculation must be done on main."); NSAssert([self css_usesFlexbox], @"CSS Layout is not enabled for this view."); - _attachNodesRecursive(self); + CLKAttachNodesFromViewHierachy(self); const CSSNodeRef node = [self cssNode]; CSSNodeCalculateLayout( @@ -188,12 +180,24 @@ - (void)css_applyLayout { [self css_sizeThatFits:self.bounds.size]; - _updateFrameRecursive(self); + CLKApplyLayoutToViewHierarchy(self); } #pragma mark - Private -static CSSSize _measure( +- (CSSNodeRef)cssNode +{ + CSSNodeBridge *node = objc_getAssociatedObject(self, @selector(cssNode)); + if (!node) { + node = [CSSNodeBridge new]; + CSSNodeSetContext(node.cnode, (__bridge void *) self); + objc_setAssociatedObject(self, @selector(cssNode), node, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + + return node.cnode; +} + +static CSSSize CLKMeasureView( CSSNodeRef node, float width, CSSMeasureMode widthMode, @@ -210,12 +214,12 @@ static CSSSize _measure( }]; return (CSSSize) { - .width = _sanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), - .height = _sanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), + .width = CLKSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), + .height = CLKSanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), }; } -static CGFloat _sanitizeMeasurement( +static CGFloat CLKSanitizeMeasurement( CGFloat constrainedSize, CGFloat measuredSize, CSSMeasureMode measureMode) @@ -232,14 +236,14 @@ static CGFloat _sanitizeMeasurement( return result; } -static void _attachNodesRecursive(UIView *view) { +static void CLKAttachNodesFromViewHierachy(UIView *view) { CSSNodeRef node = [view cssNode]; const BOOL usesFlexbox = [view css_usesFlexbox]; const BOOL isLeaf = !usesFlexbox || view.subviews.count == 0; // Only leaf nodes should have a measure function if (isLeaf) { - CSSNodeSetMeasureFunc(node, _measure); + CSSNodeSetMeasureFunc(node, CLKMeasureView); // Clear any children while (CSSNodeChildCount(node) > 0) { @@ -254,7 +258,7 @@ static void _attachNodesRecursive(UIView *view) { if (CSSNodeChildCount(node) < i + 1 || CSSNodeGetChild(node, i) != childNode) { CSSNodeInsertChild(node, childNode, i); } - _attachNodesRecursive(view.subviews[i]); + CLKAttachNodesFromViewHierachy(view.subviews[i]); } // Remove any children which were removed since the last call to css_applyLayout @@ -264,7 +268,7 @@ static void _attachNodesRecursive(UIView *view) { } } -static CGFloat _roundPixelValue(CGFloat value) +static CGFloat CLKRoundPixelValue(CGFloat value) { static CGFloat scale; static dispatch_once_t onceToken; @@ -275,7 +279,7 @@ static CGFloat _roundPixelValue(CGFloat value) return round(value * scale) / scale; } -static void _updateFrameRecursive(UIView *view) { +static void CLKApplyLayoutToViewHierarchy(UIView *view) { NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread."); CSSNodeRef node = [view cssNode]; @@ -291,19 +295,19 @@ static void _updateFrameRecursive(UIView *view) { view.frame = (CGRect) { .origin = { - .x = _roundPixelValue(topLeft.x), - .y = _roundPixelValue(topLeft.y), + .x = CLKRoundPixelValue(topLeft.x), + .y = CLKRoundPixelValue(topLeft.y), }, .size = { - .width = _roundPixelValue(bottomRight.x) - _roundPixelValue(topLeft.x), - .height = _roundPixelValue(bottomRight.y) - _roundPixelValue(topLeft.y), + .width = CLKRoundPixelValue(bottomRight.x) - CLKRoundPixelValue(topLeft.x), + .height = CLKRoundPixelValue(bottomRight.y) - CLKRoundPixelValue(topLeft.y), }, }; const BOOL isLeaf = ![view css_usesFlexbox] || view.subviews.count == 0; if (!isLeaf) { for (NSUInteger i = 0; i < view.subviews.count; i++) { - _updateFrameRecursive(view.subviews[i]); + CLKApplyLayoutToViewHierarchy(view.subviews[i]); } } }