diff --git a/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java b/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java index e11cbaa68..5316086c3 100644 --- a/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java +++ b/android/widgets/src/main/java/org/nativescript/widgets/FlexboxLayout.java @@ -1071,9 +1071,24 @@ public class FlexboxLayout extends ViewGroup { } else { accumulatedRoundError = rawCalculatedWidth - roundedCalculatedWidth; } - child.measure(MeasureSpec.makeMeasureSpec(roundedCalculatedWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), - MeasureSpec.EXACTLY)); + + int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(roundedCalculatedWidth, MeasureSpec.EXACTLY); + + // NOTE: for controls that support internal content wrapping (e.g. TextView) reducing the width + // might result in increased height e.g. text that could be shown on one line for larger + // width needs to be wrapped in two when width is reduced. + // As a result we cannot unconditionally measure with EXACTLY the current measured height + int childHeightMeasureSpec = getChildMeasureSpec(this.getMeasuredHeightAndState(), + getPaddingTop() + getPaddingBottom() + lp.topMargin + + lp.bottomMargin, lp.height < 0 ? LayoutParams.WRAP_CONTENT : lp.height); + + child.measure(childWidthMeasureSpec, childHeightMeasureSpec); + + // make sure crossSize is up-to-date as child calculated height might have increased + flexLine.mCrossSize = Math.max( + flexLine.mCrossSize, + child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin + ); } flexLine.mMainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } else { diff --git a/ios/TNSWidgets/TNSWidgets/TNSLabel.m b/ios/TNSWidgets/TNSWidgets/TNSLabel.m index 1f83846b4..66191b842 100644 --- a/ios/TNSWidgets/TNSWidgets/TNSLabel.m +++ b/ios/TNSWidgets/TNSWidgets/TNSLabel.m @@ -12,13 +12,27 @@ - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { - CGSize size = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines].size; - return CGRectMake( - - (self.borderThickness.left + self.padding.left), - - (self.borderThickness.right + self.padding.right), - size.width + self.borderThickness.left + self.padding.left + self.padding.right + self.borderThickness.right, - size.height + self.borderThickness.top + self.padding.top + self.padding.bottom + self.borderThickness.bottom - ); + // UILabel.textRectForBounds:limitedToNumberOfLines: returns rect with CGSizeZero when empty + if (self.text.length == 0) { + return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; + } + + // 1. Subtract the insets (border thickness & padding) + // 2. Calculate the original label bounds + // 3. Add the insets again + UIEdgeInsets insets = UIEdgeInsetsMake(self.borderThickness.top + self.padding.top, + self.borderThickness.left + self.padding.left, + self.borderThickness.bottom + self.padding.bottom, + self.borderThickness.right + self.padding.right); + + CGRect rect = [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, insets) limitedToNumberOfLines:numberOfLines]; + + UIEdgeInsets inverseInsets = UIEdgeInsetsMake(-(self.borderThickness.top + self.padding.top), + -(self.borderThickness.left + self.padding.left), + -(self.borderThickness.bottom + self.padding.bottom), + -(self.borderThickness.right + self.padding.right)); + + return UIEdgeInsetsInsetRect(rect, inverseInsets); } -(void)drawTextInRect:(CGRect)rect {