-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix measurement of Row and Column on iOS inside of UIStackView #2426
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More ComposeUI layouts that are broken. This is a problem, but it’s not new and it’s not urgent.
this.alignment = UIStackViewAlignmentLeading | ||
this.distribution = UIStackViewDistributionFill | ||
this.alignment = UIStackViewAlignmentFill | ||
this.distribution = UIStackViewDistributionEqualSpacing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had better luck with these ones
@@ -144,8 +144,8 @@ class UIViewScrollWrapper : ScrollWrapper<UIView> { | |||
scrollView.addSubview(value) | |||
value.translatesAutoresizingMaskIntoConstraints = false | |||
value.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true | |||
value.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s way too cute, but UIScrollView scrolls horizontally if you bind leading
and trailing
, but doesn’t scroll horizontally if you bind leading
and width
.
override fun invalidateIntrinsicContentSize() { | ||
super.invalidateIntrinsicContentSize() | ||
this.widthForIntrinsicSize = UIViewNoIntrinsicMetric | ||
this.heightForIntrinsicSize = UIViewNoIntrinsicMetric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t have a test case to prove that this override is necessary. I might try to make one? That might be tricky
redwood-layout-uiview/src/commonMain/kotlin/app/cash/redwood/layout/uiview/YogaUIView.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥 🔥
a77d94a
to
c3828da
Compare
d861e69
to
483577f
Compare
c3828da
to
0aa3561
Compare
* We work around this by: | ||
* | ||
* 1. Making [intrinsicContentSize] depend on the mostly-recently applied bounds | ||
* 2. Invalidating it each time the bounds change |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This work around sounds good to me, though @edahle do you know how a UITextView
and other views that depend on knowing the width to compute the height provide a reasonable intrinsicContentSize
? Maybe private APIs of some kind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UILabel has a feature called preferredMaxLayoutWidth that you can use for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this! 🙏🏻
UIStackView uses UIView.intrinsicContentSize on its subviews, but our Row and Column implementations don't have a natural implementation of this API. In particular, if any subview wraps its contents (so its height depends on its available width), there's no single intrinsicContentSize(). We work around this by following some online advice: invalidate the intrinsic size when the bounds change, and then use those bounds when computing the new intrinsic size. This is more fragile and stateful than I'd like, but it seems like a common practice for working around UIStackView's API.
0aa3561
to
581c732
Compare
UIStackView uses UIView.intrinsicContentSize on its subviews, but our Row and Column implementations don't have a natural implementation of this API. In particular, if any subview wraps its contents (so its height depends on its available width), there's no single intrinsicContentSize().
We work around this by following some online advice: invalidate the intrinsic size when the bounds change, and then use those bounds when computing the new intrinsic size.
This is more fragile and stateful than I'd like, but it seems like a common practice for working around UIStackView's API.
CHANGELOG.md
's "Unreleased" section has been updated, if applicable.