Hey everyone, does someone know how to properly gr...
# compose-ios
l
Hey everyone, does someone know how to properly grab a UIKitViewController and make it wrap its children vertically? Every sample I've come across work with
fillMaxSize()
which if you want to for example show a native text view looks bad (as shown on screenshot) I'd like to preferably get rid of the white background (which can be done by color change) and the forced size by me to 100dp, if I remove manually set height, the resulting height is just 0 which is not what I want
v
If you're talking about having an
IOS
view wrap its
Compose
children it might be difficult. I know we had issues with bottomSheets that were supposed to wrap content. If you're interested, I can go into the details of the workaround we've done.
l
I've made some workarounds that work fine, but still can't figure out how the white background is rendered. I believe it should take it's parents background by default. And to specify, I was talking about
Compose
wrapping its
iOS views
r
It's either setting a fixed size or filling the max size. You could set the size once your composable knows it (modifier) and then use a callback to report to SwiftUi and then set its height fixed again, right?
l
Yes, I actually do it the other way around. I let the
UIKitView
apply
sizeToFit()
which does what I need it to do (also one can use in swiftUI the
.frame()
function to further modify the behavior) and then in
onResize()
I get the final size which I apply to the wrapping view. It's more comprehensible with the code:
Copy code
@OptIn(ExperimentalForeignApi::class)
@Composable
actual fun NativeText(text: String, modifier: Modifier, backgroundColor: Color) {
    val factory = LocalNativeTextViewFactory.current

    // It's very tricky to do wrap content on injected views, so
    // I guess we need to do this on per-view basis
    var viewSize by remember { mutableStateOf(DpSize.Zero) }
    Box(modifier.then(if (viewSize == DpSize.Zero) Modifier.fillMaxWidth().height(100.dp) else Modifier.size(viewSize))) {
        UIKitViewController(
            modifier = modifier.fillMaxSize(),
            factory = {
                factory.getView(text)
            },
            background = backgroundColor,
            onResize = { controller, size ->
                controller.view.apply {
                    // We set the original frame (compose wrapper rect) to the UIKitView
                    setFrame(size)
                    // We force the UIKitView to measure itself to tell us how much size it actually takes
                    // (this can be further modified by using .frame() in swiftUI for example
                    sizeToFit()
                    // We take the newly calculated size and force it to the box wrapping the frame (therefore we have no blank space)
                    frame.useContents {
                        val actualHeight = this.size.height
                        val actualWidth = this.size.width
                        viewSize = DpSize(actualWidth.dp, actualHeight.dp)
                    }
                    this.backgroundColor = UIColor.clearColor
                    this.opaque = true
                    this.setClipsToBounds(true)
                }
            }
        )
    }
}
e
You can try your luck with using https://developer.apple.com/documentation/uikit/uiview/1622624-systemlayoutsizefitting I wanted to explore possibilities for intrinsic size measurement of native views for compose layout and it seems like a nice place to start
👀 1
l
Added a PR if anyone wants to check it out: https://github.com/JetBrains/compose-multiplatform-core/pull/1432 Any feedback is welcome!
👍 5
K 3
m
Great initiative!!