최근에 KMP 프로젝트에서 UI/UX 개선 작업을 진행했는데, 생각보다 까다로운 부분들이 많았다. 특히 iOS와 안드로이드의 차이점을 처리하는 게 제일 골치 아팠음. 그래도 하나씩 해결하면서 많이 배웠으니 정리해보려고 함.
iOS에서 홈 인디케이터(━)와 앱 바텀바가 다른 색상으로 나와서 UI가 분리되어 보였다. 게다가 바텀바 높이도 너무 커서 공간 낭비가 심했음.
먼저 iOS Safe Area 처리부터 손봤다.
// MainViewController.kt - iOS Safe Area 처리
fun MainViewController() = ComposeUIViewController {
App(modifier = Modifier
.fillMaxSize()
.imePadding() // 키보드 패딩 처리
)
}
그다음 바텀바 설정을 개선했다.
// App.kt - 바텀바 설정
NavigationBar(
containerColor = MaterialTheme.colorScheme.surface, // 상단바와 동일한 색상
modifier = Modifier.height(56.dp) // 높이 축소
) {
// NavigationBarItems...
}
.imePadding()
: 키보드가 올라올 때 UI가 가려지지 않도록 자동으로 패딩을 조정해줌MaterialTheme.colorScheme.surface
사용통화 선택할 때 FilterChip들이 가로로 쭉 나열되어서 공간을 너무 많이 차지했다. 통화 옵션이 많을 때는 UI가 복잡해져서 사용성이 떨어졌음.
// 기존: FilterChip 방식
Row {
currencies.forEach { currency ->
FilterChip(
selected = selectedCurrency == currency,
onClick = { selectedCurrency = currency },
label = { Text(currency) }
)
}
}
// 개선: 드롭다운 방식
ExposedDropdownMenuBox(
expanded = expandedCurrency,
onExpandedChange = { expandedCurrency = !expandedCurrency }
) {
OutlinedTextField(
value = selectedCurrency,
readOnly = true,
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expandedCurrency) },
modifier = Modifier.menuAnchor().fillMaxWidth()
)
ExposedDropdownMenu(
expanded = expandedCurrency,
onDismissRequest = { expandedCurrency = false }
) {
currencies.forEach { currency ->
DropdownMenuItem(
text = { Text(currency) },
onClick = {
selectedCurrency = currency
expandedCurrency = false
}
)
}
}
}
안드로이드에서 enableEdgeToEdge()
를 사용하면서 콘텐츠가 시스템 바 영역까지 확장되어 바텀바가 콘텐츠를 가리는 현상이 발생했다. 특히 API 35+ 에서는 edge-to-edge가 강제 정책이라 더 신경써야 했음.
// MainActivity.kt
enableEdgeToEdge() // 콘텐츠가 시스템 바 영역까지 확장
Scaffold(
modifier = modifier
.fillMaxSize()
.systemBarsPadding(), // 시스템 바 영역 자동 패딩
topBar = { /* ... */ },
bottomBar = { /* ... */ }
) { paddingValues ->
// 콘텐츠 영역
}
systemBarsPadding()
: 상태바와 네비게이션바 높이를 자동으로 감지해서 패딩 적용// iOS - MainViewController
.imePadding() // 키보드 대응
// 공통 - Scaffold
.systemBarsPadding() // 시스템 바 대응
ExposedDropdownMenuBox
: 드롭다운 UI 구현할 때 최고FilterChip
: 토글 방식 선택 UI에 적합// MainActivity
enableEdgeToEdge()
// Compose
Scaffold(modifier = Modifier.systemBarsPadding())
이번 개선 작업을 통해 iOS와 안드로이드 모두에서 일관되고 현대적인 UI/UX를 제공할 수 있게 되었다. 특히 시스템 바 처리와 컴포넌트 선택에 있어서 많이 배웠음. KMP에서 UI 작업할 때는 플랫폼별 특성을 잘 이해하고 적절한 Modifier를 사용하는 게 핵심인 것 같다.
앞으로도 이런 세부적인 UX 개선에 더 신경써야겠음!