Summary: Fixes #606. If there are no subviews in `UIView`, yoga assumes that `sizeThatFits:` returns `CGSizeZero`. However, according to [the documentation](https://developer.apple.com/documentation/uikit/uiview/1622625-sizethatfits), `UIView` returns current size if there are no subviews. This diff adds a check - if there are no subviews, `sizeThatFits:` doesn't get called, and CGSizeZero is returned. Pull Request resolved: https://github.com/facebook/yoga/pull/610 Reviewed By: davidaurelio Differential Revision: D6807406 Pulled By: priteshrnandgaonkar fbshipit-source-id: 9189cf14c393f840122bc365d3827881bf03548c
This commit is contained in:
committed by
Facebook Github Bot
parent
786ccddd7b
commit
838ef47847
@@ -129,6 +129,7 @@ static YGConfigRef globalConfig;
|
|||||||
@interface YGLayout ()
|
@interface YGLayout ()
|
||||||
|
|
||||||
@property (nonatomic, weak, readonly) UIView *view;
|
@property (nonatomic, weak, readonly) UIView *view;
|
||||||
|
@property(nonatomic, assign, readonly) BOOL isUIView;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -153,6 +154,7 @@ static YGConfigRef globalConfig;
|
|||||||
YGNodeSetContext(_node, (__bridge void *) view);
|
YGNodeSetContext(_node, (__bridge void *) view);
|
||||||
_isEnabled = NO;
|
_isEnabled = NO;
|
||||||
_isIncludedInLayout = YES;
|
_isIncludedInLayout = YES;
|
||||||
|
_isUIView = [view isMemberOfClass:[UIView class]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -331,10 +333,20 @@ static YGSize YGMeasureView(
|
|||||||
const CGFloat constrainedHeight = (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX: height;
|
const CGFloat constrainedHeight = (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX: height;
|
||||||
|
|
||||||
UIView *view = (__bridge UIView*) YGNodeGetContext(node);
|
UIView *view = (__bridge UIView*) YGNodeGetContext(node);
|
||||||
const CGSize sizeThatFits = [view sizeThatFits:(CGSize) {
|
CGSize sizeThatFits = CGSizeZero;
|
||||||
|
|
||||||
|
// The default implementation of sizeThatFits: returns the existing size of
|
||||||
|
// the view. That means that if we want to layout an empty UIView, which
|
||||||
|
// already has got a frame set, its measured size should be CGSizeZero, but
|
||||||
|
// UIKit returns the existing size.
|
||||||
|
//
|
||||||
|
// See https://github.com/facebook/yoga/issues/606 for more information.
|
||||||
|
if (!view.yoga.isUIView || [view.subviews count] > 0) {
|
||||||
|
sizeThatFits = [view sizeThatFits:(CGSize){
|
||||||
.width = constrainedWidth,
|
.width = constrainedWidth,
|
||||||
.height = constrainedHeight,
|
.height = constrainedHeight,
|
||||||
}];
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
return (YGSize) {
|
return (YGSize) {
|
||||||
.width = YGSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode),
|
.width = YGSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode),
|
||||||
|
@@ -127,6 +127,15 @@
|
|||||||
XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width);
|
XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testSizeThatFitsEmptyView {
|
||||||
|
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 200, 200)];
|
||||||
|
view.yoga.isEnabled = YES;
|
||||||
|
|
||||||
|
const CGSize viewSize = view.yoga.intrinsicSize;
|
||||||
|
XCTAssertEqual(viewSize.height, 0);
|
||||||
|
XCTAssertEqual(viewSize.width, 0);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)testPreservingOrigin
|
- (void)testPreservingOrigin
|
||||||
{
|
{
|
||||||
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,75)];
|
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,75)];
|
||||||
|
Reference in New Issue
Block a user