Compose Multiplatform에서 엣지 투 엣지
Android는 SDK 35 이상을 대상으로 하는 앱에 엣지 투 엣지를 강제하며, 36에서는 옵트아웃이 사라집니다. iOS 앱은 상태 표시줄과 홈 인디케이터 아래에 콘텐츠를 그리는 것이 일반적입니다. 처음부터 모든 화면을 엣지 투 엣지로 구축하세요.
규칙: 배경은 시스템 바 뒤에 그려지고, 콘텐츠와 컨트롤은 인셋으로 패딩됩니다.
활성화하기
Android (androidApp의 MainActivity), setContent 전:
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent { App() }
}
매니페스트에서 액티비티에 android:windowSoftInputMode="adjustResize"를 설정하여 IME 인셋이 Compose에 도달하도록 합니다.
iOS (ContentView.swift): Compose가 전체 화면을 소유하도록 합니다. 그렇지 않으면 SwiftUI가 먼저 safe area를 적용하고 Compose는 인셋이 0인 상태가 됩니다.
ComposeView().ignoresSafeArea()
Scaffold가 대부분의 작업을 수행합니다
Scaffold(
topBar = { TopAppBar(title = { Text(title) }) }, // 상태 표시줄에 대해 자체 패딩 처리
bottomBar = { NavigationBar { /* ... */ } }, // 네비게이션 바에 대해 자체 패딩 처리
) { innerPadding ->
LazyColumn(
contentPadding = innerPadding, // 콘텐츠가 바 아래에서 스크롤됨
modifier = Modifier.fillMaxSize(),
) { /* items */ }
}
- 항상
innerPadding을 사용하세요. 리스트의 경우contentPadding으로 전달하여 항목이 반투명 바 뒤에서 스크롤되도록 하고, 스크롤되지 않는 콘텐츠의 경우Modifier.padding(innerPadding)을 사용하세요. - Material 3 바는 자체 인셋을 소비합니다.
TopAppBar위에statusBarsPadding()을 추가하지 마세요. - 중첩된 Scaffold는 패딩을 두 배로 만듭니다. 내부 Scaffold에는
contentWindowInsets = WindowInsets(0)을 지정하거나 외부 콘텐츠에consumeWindowInsets(innerPadding)을 적용하세요.
Scaffold가 없는 화면
Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) { // 배경이 화면을 채웁니다
Column(Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing)) { /* 콘텐츠 */ }
}
WindowInsets.safeDrawing은 상태 표시줄, 네비게이션 바, 디스플레이 컷아웃 및 키보드를 포함합니다. 제스처가 중요할 때는 safeContent를 사용하세요. 인셋 패딩은 콘텐츠를 소유하는 수준에서 한 번만 적용하고, 부모와 자식 모두에 적용하지 마세요.
키보드
- 입력 화면: 스크롤 컨테이너에
Modifier.imePadding()을 사용하거나, 이미 IME를 포함하는safeDrawing을 사용하세요. - 키보드 위에 있어야 하는 하단 버튼: Scaffold
bottomBar에Modifier.imePadding()과 함께 배치하거나WindowInsets.ime.union(WindowInsets.navigationBars)를 사용하세요. - 콘텐츠를 스크롤 가능하게 만들어 포커스된 필드가 보이도록 하세요.
전체 화면 콘텐츠
이미지, 지도, 동영상 및 카메라 미리보기는 인셋을 무시하고 화면을 채워야 합니다. 컨트롤을 상단에 오버레이하고 WindowInsets.safeDrawing으로 컨트롤만 패딩 처리하세요.
시스템 바 대비
바는 투명하므로 아이콘 대비는 사용자의 책임입니다. Android에서 enableEdgeToEdge()는 시스템 테마에서 밝거나 어두운 아이콘을 선택합니다. 앱에 자체 테마 전환이 있는 경우 테마가 변경될 때 일치하는 SystemBarStyle과 함께 다시 호출하세요. 세 버튼 네비게이션에서 Android는 반투명 스크림을 추가합니다. 하단 바가 이미 단색 배경을 제공하지 않는 한 그대로 두세요.
광고 배너
하단 배너는 Scaffold bottomBar 슬롯 내부, 네비게이션 바 인셋 위에 배치되며, 콘텐츠가 튀지 않도록 높이가 예약됩니다. 배너가 제스처 바 아래에 위치하거나 네비게이션 컨트롤과 겹치지 않도록 하세요. 이는 레이아웃 버그이자 광고 정책 문제입니다.
모든 화면을 위한 체크리스트
- 배경이 위아래 물리적 가장자리까지 도달합니다.
- 상태 표시줄, 컷아웃, 네비게이션 바 또는 홈 인디케이터 아래에 텍스트나 컨트롤이 없습니다.
- 마지막 리스트 항목이 하단 바 위로 완전히 스크롤될 수 있습니다.
- 포커스된 텍스트 필드가 키보드가 열린 상태에서도 보입니다.
- 가로 모드(컷아웃이 측면에 있음)와 어두운 테마에서 올바르게 보입니다.
- 인셋이 한 번만 적용되고 두 배가 되지 않습니다.
Google의 edge-to-edge 스킬이 설치되어 있다면 이를 사용하여 Android 관련 문제를 해결하세요.