Better (right) implementation of `intrinsicContentSize`
Reviewed By: emilsjolander Differential Revision: D4486767 fbshipit-source-id: d37ea11f9f48425d4d99c29e8bfb6c8ed2353f04
This commit is contained in:
parent
31099aa233
commit
d1990f8fc4
|
@ -28,11 +28,10 @@
|
|||
{
|
||||
[super setUp];
|
||||
|
||||
self.parentView = [self _shadowViewWithConfig:^(YGNodeRef node) {
|
||||
YGNodeStyleSetFlexDirection(node, YGFlexDirectionColumn);
|
||||
YGNodeStyleSetWidth(node, 440);
|
||||
YGNodeStyleSetHeight(node, 440);
|
||||
}];
|
||||
self.parentView = [RCTRootShadowView new];
|
||||
YGNodeStyleSetFlexDirection(self.parentView.cssNode, YGFlexDirectionColumn);
|
||||
YGNodeStyleSetWidth(self.parentView.cssNode, 440);
|
||||
YGNodeStyleSetHeight(self.parentView.cssNode, 440);
|
||||
self.parentView.reactTag = @1; // must be valid rootView tag
|
||||
}
|
||||
|
||||
|
@ -132,6 +131,7 @@
|
|||
- (void)testAssignsSuggestedWidthDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetHeight(node, 10);
|
||||
|
@ -143,6 +143,7 @@
|
|||
- (void)testAssignsSuggestedHeightDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
|
@ -154,6 +155,7 @@
|
|||
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||
YGNodeStyleSetWidth(node, 10);
|
||||
|
@ -189,11 +191,12 @@
|
|||
NSStringFromCGRect(actualRect));
|
||||
}
|
||||
|
||||
- (RCTRootShadowView *)_shadowViewWithConfig:(void(^)(YGNodeRef node))configBlock
|
||||
- (RCTShadowView *)_shadowViewWithConfig:(void(^)(YGNodeRef node))configBlock
|
||||
{
|
||||
RCTRootShadowView *shadowView = [RCTRootShadowView new];
|
||||
RCTShadowView *shadowView = [RCTShadowView new];
|
||||
configBlock(shadowView.cssNode);
|
||||
return shadowView;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -473,11 +473,12 @@ dispatch_queue_t RCTGetUIManagerQueue(void)
|
|||
NSNumber *reactTag = view.reactTag;
|
||||
dispatch_async(RCTGetUIManagerQueue(), ^{
|
||||
RCTShadowView *shadowView = self->_shadowViewRegistry[reactTag];
|
||||
RCTAssert(shadowView != nil, @"Could not locate root view with tag #%@", reactTag);
|
||||
RCTAssert(shadowView != nil, @"Could not locate view with tag #%@", reactTag);
|
||||
|
||||
shadowView.intrinsicContentSize = size;
|
||||
|
||||
[self setNeedsLayout];
|
||||
if (!CGSizeEqualToSize(shadowView.intrinsicContentSize, size)) {
|
||||
shadowView.intrinsicContentSize = size;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -81,15 +81,16 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
|
|||
|
||||
@property (nonatomic, assign) CGRect frame;
|
||||
|
||||
/**
|
||||
* Represents the natural size of the view, which is used when explicit size is not set or is ambiguous.
|
||||
* Defaults to `{UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric}`.
|
||||
*/
|
||||
@property (nonatomic, assign) CGSize intrinsicContentSize;
|
||||
|
||||
|
||||
- (void)setTopLeft:(CGPoint)topLeft;
|
||||
- (void)setSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* Set the natural size of the view, which is used when no explicit size is set.
|
||||
* Use UIViewNoIntrinsicMetric to ignore a dimension.
|
||||
*/
|
||||
- (void)setIntrinsicContentSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* Border. Defaults to { 0, 0, 0, 0 }.
|
||||
*/
|
||||
|
|
|
@ -301,6 +301,8 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT],
|
|||
_borderMetaProps[ii] = YGValueUndefined;
|
||||
}
|
||||
|
||||
_intrinsicContentSize = CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
|
||||
|
||||
_newView = YES;
|
||||
_propagationLifecycle = RCTUpdateLifecycleUninitialized;
|
||||
_textLifecycle = RCTUpdateLifecycleUninitialized;
|
||||
|
@ -556,30 +558,59 @@ RCT_POSITION_PROPERTY(Left, left, YGEdgeStart)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void RCTAssignSuggestedDimension(YGNodeRef cssNode, YGDimension dimension, CGFloat amount)
|
||||
static inline YGSize RCTShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
|
||||
{
|
||||
if (amount != UIViewNoIntrinsicMetric) {
|
||||
switch (dimension) {
|
||||
case YGDimensionWidth:
|
||||
if (YGNodeStyleGetWidth(cssNode).unit == YGUnitUndefined) {
|
||||
YGNodeStyleSetWidth(cssNode, amount);
|
||||
}
|
||||
break;
|
||||
case YGDimensionHeight:
|
||||
if (YGNodeStyleGetHeight(cssNode).unit == YGUnitUndefined) {
|
||||
YGNodeStyleSetHeight(cssNode, amount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node);
|
||||
|
||||
CGSize intrinsicContentSize = shadowView->_intrinsicContentSize;
|
||||
// Replace `UIViewNoIntrinsicMetric` (which equals `-1`) with zero.
|
||||
intrinsicContentSize.width = MAX(0, intrinsicContentSize.width);
|
||||
intrinsicContentSize.height = MAX(0, intrinsicContentSize.height);
|
||||
|
||||
YGSize result;
|
||||
|
||||
switch (widthMode) {
|
||||
case YGMeasureModeUndefined:
|
||||
result.width = intrinsicContentSize.width;
|
||||
break;
|
||||
case YGMeasureModeExactly:
|
||||
result.width = width;
|
||||
break;
|
||||
case YGMeasureModeAtMost:
|
||||
result.width = MIN(width, intrinsicContentSize.width);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (heightMode) {
|
||||
case YGMeasureModeUndefined:
|
||||
result.height = intrinsicContentSize.height;
|
||||
break;
|
||||
case YGMeasureModeExactly:
|
||||
result.height = height;
|
||||
break;
|
||||
case YGMeasureModeAtMost:
|
||||
result.height = MIN(height, intrinsicContentSize.height);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setIntrinsicContentSize:(CGSize)size
|
||||
- (void)setIntrinsicContentSize:(CGSize)intrinsicContentSize
|
||||
{
|
||||
if (YGNodeStyleGetFlexGrow(_cssNode) == 0 && YGNodeStyleGetFlexShrink(_cssNode) == 0) {
|
||||
RCTAssignSuggestedDimension(_cssNode, YGDimensionHeight, size.height);
|
||||
RCTAssignSuggestedDimension(_cssNode, YGDimensionWidth, size.width);
|
||||
if (CGSizeEqualToSize(_intrinsicContentSize, intrinsicContentSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_intrinsicContentSize = intrinsicContentSize;
|
||||
|
||||
if (CGSizeEqualToSize(_intrinsicContentSize, CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric))) {
|
||||
YGNodeSetMeasureFunc(_cssNode, NULL);
|
||||
} else {
|
||||
YGNodeSetMeasureFunc(_cssNode, RCTShadowViewMeasure);
|
||||
}
|
||||
|
||||
YGNodeMarkDirty(_cssNode);
|
||||
}
|
||||
|
||||
- (void)setTopLeft:(CGPoint)topLeft
|
||||
|
|
Loading…
Reference in New Issue