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];
|
[super setUp];
|
||||||
|
|
||||||
self.parentView = [self _shadowViewWithConfig:^(YGNodeRef node) {
|
self.parentView = [RCTRootShadowView new];
|
||||||
YGNodeStyleSetFlexDirection(node, YGFlexDirectionColumn);
|
YGNodeStyleSetFlexDirection(self.parentView.cssNode, YGFlexDirectionColumn);
|
||||||
YGNodeStyleSetWidth(node, 440);
|
YGNodeStyleSetWidth(self.parentView.cssNode, 440);
|
||||||
YGNodeStyleSetHeight(node, 440);
|
YGNodeStyleSetHeight(self.parentView.cssNode, 440);
|
||||||
}];
|
|
||||||
self.parentView.reactTag = @1; // must be valid rootView tag
|
self.parentView.reactTag = @1; // must be valid rootView tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +131,7 @@
|
||||||
- (void)testAssignsSuggestedWidthDimension
|
- (void)testAssignsSuggestedWidthDimension
|
||||||
{
|
{
|
||||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||||
|
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||||
YGNodeStyleSetHeight(node, 10);
|
YGNodeStyleSetHeight(node, 10);
|
||||||
|
@ -143,6 +143,7 @@
|
||||||
- (void)testAssignsSuggestedHeightDimension
|
- (void)testAssignsSuggestedHeightDimension
|
||||||
{
|
{
|
||||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||||
|
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||||
YGNodeStyleSetWidth(node, 10);
|
YGNodeStyleSetWidth(node, 10);
|
||||||
|
@ -154,6 +155,7 @@
|
||||||
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
||||||
{
|
{
|
||||||
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
[self _withShadowViewWithStyle:^(YGNodeRef node) {
|
||||||
|
YGNodeStyleSetPositionType(node, YGPositionTypeAbsolute);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
YGNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
||||||
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
YGNodeStyleSetPosition(node, YGEdgeTop, 0);
|
||||||
YGNodeStyleSetWidth(node, 10);
|
YGNodeStyleSetWidth(node, 10);
|
||||||
|
@ -189,11 +191,12 @@
|
||||||
NSStringFromCGRect(actualRect));
|
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);
|
configBlock(shadowView.cssNode);
|
||||||
return shadowView;
|
return shadowView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -473,11 +473,12 @@ dispatch_queue_t RCTGetUIManagerQueue(void)
|
||||||
NSNumber *reactTag = view.reactTag;
|
NSNumber *reactTag = view.reactTag;
|
||||||
dispatch_async(RCTGetUIManagerQueue(), ^{
|
dispatch_async(RCTGetUIManagerQueue(), ^{
|
||||||
RCTShadowView *shadowView = self->_shadowViewRegistry[reactTag];
|
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;
|
if (!CGSizeEqualToSize(shadowView.intrinsicContentSize, size)) {
|
||||||
|
shadowView.intrinsicContentSize = size;
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,15 +81,16 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
|
||||||
|
|
||||||
@property (nonatomic, assign) CGRect frame;
|
@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)setTopLeft:(CGPoint)topLeft;
|
||||||
- (void)setSize:(CGSize)size;
|
- (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 }.
|
* Border. Defaults to { 0, 0, 0, 0 }.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -301,6 +301,8 @@ static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT],
|
||||||
_borderMetaProps[ii] = YGValueUndefined;
|
_borderMetaProps[ii] = YGValueUndefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_intrinsicContentSize = CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
|
||||||
|
|
||||||
_newView = YES;
|
_newView = YES;
|
||||||
_propagationLifecycle = RCTUpdateLifecycleUninitialized;
|
_propagationLifecycle = RCTUpdateLifecycleUninitialized;
|
||||||
_textLifecycle = 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) {
|
RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node);
|
||||||
switch (dimension) {
|
|
||||||
case YGDimensionWidth:
|
CGSize intrinsicContentSize = shadowView->_intrinsicContentSize;
|
||||||
if (YGNodeStyleGetWidth(cssNode).unit == YGUnitUndefined) {
|
// Replace `UIViewNoIntrinsicMetric` (which equals `-1`) with zero.
|
||||||
YGNodeStyleSetWidth(cssNode, amount);
|
intrinsicContentSize.width = MAX(0, intrinsicContentSize.width);
|
||||||
}
|
intrinsicContentSize.height = MAX(0, intrinsicContentSize.height);
|
||||||
break;
|
|
||||||
case YGDimensionHeight:
|
YGSize result;
|
||||||
if (YGNodeStyleGetHeight(cssNode).unit == YGUnitUndefined) {
|
|
||||||
YGNodeStyleSetHeight(cssNode, amount);
|
switch (widthMode) {
|
||||||
}
|
case YGMeasureModeUndefined:
|
||||||
break;
|
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) {
|
if (CGSizeEqualToSize(_intrinsicContentSize, intrinsicContentSize)) {
|
||||||
RCTAssignSuggestedDimension(_cssNode, YGDimensionHeight, size.height);
|
return;
|
||||||
RCTAssignSuggestedDimension(_cssNode, YGDimensionWidth, size.width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_intrinsicContentSize = intrinsicContentSize;
|
||||||
|
|
||||||
|
if (CGSizeEqualToSize(_intrinsicContentSize, CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric))) {
|
||||||
|
YGNodeSetMeasureFunc(_cssNode, NULL);
|
||||||
|
} else {
|
||||||
|
YGNodeSetMeasureFunc(_cssNode, RCTShadowViewMeasure);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNodeMarkDirty(_cssNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTopLeft:(CGPoint)topLeft
|
- (void)setTopLeft:(CGPoint)topLeft
|
||||||
|
|
Loading…
Reference in New Issue