Skip to content

ModalBottomSheet not showing on first press on iOS #151

@dalenjohnson

Description

@dalenjohnson

Describe your issue

When trying to show a ModalBottomSheet it requires 2 press of the button show the sheet on iOS.

In my sample code, the first list item button that you press seems to work fine, but the second and third one each require two presses. And then after you get them to successfully show the sheet once they seem to work correctly on every press after that, but this issue does come back after navigation. But in my actual app, every list item button that I click(including the first) requires two presses on iOS to show the sheet the first time.

One other thing that doesn't seem to show in the video below is that the screen does flash when pressing the button the first time. It's like the scrim shows for a millisecond and disappears.

RocketSim_Recording_iPhone_16_Pro_6.3_2025-11-07_16.50.35.mp4

What version of Compose Unstyled are you using?

1.47.2

What version of Compose are you using?

CMP 1.9.2 and CMP 1.10.0-alpha03

Which platforms can you reproduce the bug on?

Select one or multiple:

  • Android
  • iOS - simulator and device
  • Desktop (Windows, Linux, MacOS)
  • Web WASM
  • Web JS

Minimum reproducible code

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.composables.core.BottomSheetScope
import com.composables.core.DragIndication
import com.composables.core.ModalBottomSheet
import com.composables.core.ModalBottomSheetState
import com.composables.core.Scrim
import com.composables.core.Sheet
import com.composables.core.SheetDetent
import com.composables.core.SheetDetent.Companion.FullyExpanded
import com.composables.core.rememberModalBottomSheetState
import com.composeunstyled.Button
import com.composeunstyled.Text

@Composable
fun App() {
    val list = listOf("One", "Two", "Three")

    LazyColumn(
        modifier = Modifier
            .background(Color.White)
            .safeContentPadding()
            .fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        items(list.size) { index ->
            val sheetState = rememberModalBottomSheetState(
                initialDetent = SheetDetent.Hidden,
            )
            ListItem(
                name = list[index],
                sheetState = sheetState,
                onShowSheet = { sheetState.targetDetent = FullyExpanded },
                onDismissSheet = { sheetState.targetDetent = SheetDetent.Hidden }
            )
        }
    }
}


@Composable
fun ListItem(
    name: String,
    sheetState: ModalBottomSheetState,
    onShowSheet: () -> Unit,
    onDismissSheet: () -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween,
    ) {
        Text(name)
        Button(onClick = onShowSheet) {
            Text("Show Sheet")
        }
    }
    StyledModalBottomSheet(
        sheetState = sheetState,
        onDismiss = onDismissSheet,
    ) {
        Column(
            modifier = Modifier.fillMaxWidth().height(400.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            DragIndication()
            Text("Sheet Content for $name")
            Button(onClick = onDismissSheet ) {
                Text("Hide Sheet")
            }
        }
    }
}

@Composable
fun StyledModalBottomSheet(
    sheetState: ModalBottomSheetState,
    onDismiss: () -> Unit,
    content: @Composable (BottomSheetScope.() -> Unit)
){
    ModalBottomSheet(
        state = sheetState,
        onDismiss = onDismiss
    ) {
        Scrim()
        Sheet(
            modifier = Modifier
                .fillMaxWidth(),
            backgroundColor = Color.White,
            content = content
        )
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions