Is there a way to control which composables move u...
# compose
d
Is there a way to control which composables move up when the keybard is opened? In my code:
Copy code
Box(
        modifier = Modifier.fillMaxSize().pointerInput(Unit) { detectTapGestures(onTap = { focusManager.clearFocus() }) }
    ) {
        TextButton(
            modifier = Modifier.align(Alignment.TopEnd).padding(10.dp),
            onClick = { }
        ) {
            Text(stringResource(Res.string.help),)
        }
        Column(
            modifier = Modifier.align(Alignment.Center),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            OutlinedTextField(
Whenever I press on the TextField and it needs to move up because the keyboard is slightly in the way, the Help button at the top alos moves up, even though there is a lot of space between them. How can I make the Help message stay in place. Note: I am using compose multiplatform and ios, I set:
Copy code
fun MainViewController() = ComposeUIViewController(
    configure = {
        onFocusBehavior = OnFocusBehavior.DoNothing
    }
) { Main() }
but that only prevents the topbar from moving up, the Help message still moves up unneccesarily
e
It is possible I've done it. I would have to look back and see how I did it
👀 1
z
If your app is handling insets itself and your field is in a vertical scroll container, then by default the whole scrollable content will move. You could move your button out of the scroll container or maybe do something fancier like manually adjust the spacing between the button and the field based on the inset instead of just using the built in padding modifiers. But that could be tricky to get right on small screens.
d
The Box is the most outer composable, so would it count as a scrollable container here?
And yes, I've set to ignore the default insets, I am managing them myself
z
The scroll container is whatever you're applying
Modifier.verticalScroll
to, or your
LazyColumn
.
d
Then I have no scrollable container here
z
Are you applying one of the insets padding modifiers somewhere? E.g.
imePadding
,
contentPadding
, etc
d
I am applying innerPadding from a Scaffold to another Box that the Box from my code snippet is in. Removing that padding makes the Help text stay, but without that padding it is in the status bar.
z
The one that takes a `WindowInsets`? I'm not sure from the code you've posted why the button would be moving past the bounds of the layout, which is what sounds like is happening.
d
Ok so I got rid of the Scaffold (that was onyl there for testing temporarily), the Box from my code snippet is now the most outer composable. I added the padding modifier to the Box like this:
Copy code
modifier = Modifier.padding(WindowInsets.systemBars.asPaddingValues()).fillMaxSize().pointerInput(Unit) { detectTapGestures(onTap = { focusManager.clearFocus() }) }
Now the Help text is not in the status bar, but when the keyboard opens nothing moves and the textfield is obstructed
z
systemBars
doesn't include IME padding i believe. Try
safeContentPadding
d
Ok nice, with safeContentPadding it moves up, but quite a lot. Is there a way to modify for example how much it moves up, or specify that I want it to only move up to the TextField and anything below that can be obstructed?
z
Kinda – the padding is only applied to what the modifier is applied to, so you could apply it to a more inner container. But that requires a particular layout structure so might be awkward.
Things should only move up enough to account for the IME size, if it's more than that something might be double-applying it
d
Is there a way to get imePadding() not as a function but as the padding values. Because what I'm thinking is I add ime padding to my whole center column and then just subtract the height of the bottom things I want to get obstructed.
z
don't know off the top of my head exactly how, but i'd start by looking at the impl of
imePadding
d
Something like this kinda works on the column:
Copy code
modifier = Modifier.align(Alignment.Center).padding(bottom = (WindowInsets.ime.asPaddingValues().calculateBottomPadding() - 200.dp).coerceAtLeast(0.dp) ),
I'll try some more things out later but I got the general idea now. Thank you some much for the help :)
👍🏻 1
145 Views