Skip to content

Commit e5fd319

Browse files
committed
Start using systemLayoutSizeFittingSize
This way we can tell the view whether a measurement is exactly (which it should honor unconditionally), or not (which it might honor if its constraint is Fill).
1 parent 8d075fb commit e5fd319

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

redwood-layout-uiview/src/commonMain/kotlin/app/cash/redwood/layout/uiview/UIViewMeasureCallback.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import kotlinx.cinterop.CValue
2323
import kotlinx.cinterop.useContents
2424
import platform.CoreGraphics.CGSize
2525
import platform.CoreGraphics.CGSizeMake
26+
import platform.UIKit.UILayoutPriorityDefaultLow
27+
import platform.UIKit.UILayoutPriorityRequired
2628
import platform.UIKit.UIView
2729
import platform.UIKit.UIViewNoIntrinsicMetric
2830

@@ -44,15 +46,18 @@ internal object UIViewMeasureCallback : MeasureCallback {
4446
else -> height.toDouble()
4547
}
4648

47-
// The default implementation of sizeThatFits: returns the existing size of
48-
// the view. That means that if we want to layout an empty UIView, which
49-
// already has a frame set, its measured size should be CGSizeZero, but
50-
// UIKit returns the existing size. See https://github.com/facebook/yoga/issues/606
51-
// for more information.
49+
// The default implementation of sizeThatFits: returns the existing size of the view. That means
50+
// that if we want to layout an empty UIView, which already has a frame set, its measured size
51+
// should be CGSizeZero, but UIKit returns the existing size. For more information, see
52+
// https://github.com/facebook/yoga/issues/606
5253
val sizeThatFits = if (view.isMemberOfClass(UIView.`class`()) && view.typedSubviews.isEmpty()) {
5354
Size(0f, 0f)
5455
} else {
55-
view.sizeThatFits(CGSizeMake(constrainedWidth, constrainedHeight)).toSize()
56+
view.systemLayoutSizeFittingSize(
57+
targetSize = CGSizeMake(constrainedWidth, constrainedHeight),
58+
withHorizontalFittingPriority = widthMode.toFittingPriority(),
59+
verticalFittingPriority = heightMode.toFittingPriority(),
60+
).toSize()
5661
}
5762

5863
return Size(
@@ -65,3 +70,8 @@ internal object UIViewMeasureCallback : MeasureCallback {
6570
private fun CValue<CGSize>.toSize() = useContents {
6671
Size(width.toFloat(), height.toFloat())
6772
}
73+
74+
private fun MeasureMode.toFittingPriority() = when (this) {
75+
MeasureMode.Exactly -> UILayoutPriorityRequired
76+
else -> UILayoutPriorityDefaultLow
77+
}

redwood-layout-uiview/src/commonMain/kotlin/app/cash/redwood/layout/uiview/YogaUIView.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import platform.CoreGraphics.CGRectMake
2121
import platform.CoreGraphics.CGRectZero
2222
import platform.CoreGraphics.CGSize
2323
import platform.CoreGraphics.CGSizeMake
24+
import platform.UIKit.UILayoutPriority
25+
import platform.UIKit.UILayoutPriorityRequired
2426
import platform.UIKit.UIScrollView
2527
import platform.UIKit.UIScrollViewContentInsetAdjustmentBehavior.UIScrollViewContentInsetAdjustmentNever
2628
import platform.UIKit.UIScrollViewDelegateProtocol
@@ -107,6 +109,27 @@ internal class YogaUIView : UIScrollView(cValue { CGRectZero }), UIScrollViewDel
107109
}
108110
}
109111

112+
override fun systemLayoutSizeFittingSize(
113+
targetSize: CValue<CGSize>,
114+
withHorizontalFittingPriority: UILayoutPriority,
115+
verticalFittingPriority: UILayoutPriority,
116+
): CValue<CGSize> {
117+
return targetSize.useContents<CGSize, CValue<CGSize>> {
118+
calculateLayout(
119+
width = when {
120+
withHorizontalFittingPriority == UILayoutPriorityRequired -> width.toYoga()
121+
widthConstraint == Constraint.Fill -> width.toYoga()
122+
else -> Size.UNDEFINED
123+
},
124+
height = when {
125+
verticalFittingPriority == UILayoutPriorityRequired -> height.toYoga()
126+
heightConstraint == Constraint.Fill -> height.toYoga()
127+
else -> Size.UNDEFINED
128+
},
129+
)
130+
}
131+
}
132+
110133
override fun layoutSubviews() {
111134
super.layoutSubviews()
112135

redwood-lazylayout-uiview/.DS_Store

6 KB
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)