-
Notifications
You must be signed in to change notification settings - Fork 0
TagEditor에서 sheet의 detents 최적화
Note
이 문서는 태그 추가 혹은 삭제 시 올라오는 sheet의 높이 최적화 해결에 대한 문서입니다
TagEditor는 내부 콘텐츠의 실제 크기를 실시간으로 측정하여 presentationDetents에 높이(sheetHeight)를 전달합니다.
이를 통해 태그 개수에 따라 시트의 크기가 유동적으로 변하는 UI를 구현하고 있습니다.
|
|
| 포커싱 ON - 태그 입력 | 포커싱 ON - 태그 레이아웃 |
|
|
| 포커싱 OFF - 태그 입력 | 포커싱 OFF - 태그 레이아웃 |
SwiftUI의 레이아웃 시스템에서 자식 뷰의 크기를 상위 뷰로 전달하기 위해 GeometryReader를 배경(background)에 배치하는 기법을 사용합니다.
- Background Measurement Pattern:
컨텐츠(TagLayout, tagField) 뒤에 GeometryReader를 깔고, 그 위에 투명한 뷰(Color.clear)를 씌워 geometry.size.height를 읽어옵니다.
이 방식은 실제 레이아웃에 영향을 주지 않으면서 렌더링 된 뷰의 크기를 정확히 측정할 수 있습니다.
높이 계산은 크게 태그 목록 영역과 입력 필드 영역 두 부분으로 나누어 측정된 후 합산됩니다.
A. 태그 목록 영역 (tagsHeight)
-
대상:
VStack내부의 상단ScrollView영역입니다. -
측정 시점:
-
초기 로드 시 (
onAppear): 뷰가 나타난 직후DispatchQueue를 통해 비동기로 높이를 측정하여 초기값을 설정합니다. -
데이터 변경 시 (
onChange):tags배열이 변경될 때마다 레이아웃이 다시 잡히므로, 이때 변경된 높이를 재측정합니다.
-
초기 로드 시 (
-
특이 사항:
태그가 하나도 없을 때는
tagsHeight가 0이 되며, 태그가 늘어날수록ScrollView의 콘텐츠 크기만큼 높이가 증가합니다.
B. 입력 필드 영역 (fieldHeight)
-
대상: 하단의
tagField(텍스트 필드와 추가 버튼이 포함된HStack) 영역입니다. -
측정 시점: 뷰가 로드되는
onAppear시점에 측정합니다. -
보정값: 순수 컴포넌트 높이에 약
16의 여백 값을 더해(geometry.size.height + 16) 하단 여유 공간을 확보합니다.
최종적으로 시트에 적용될 높이(sheetHeight)는 앞서 측정한 두 영역의 높이와 사이 간격(spacing)을 합산하여 결정됩니다.
수식:
sheetHeight = fieldHeight + tagsHeight + spacing
-
spacing 처리:
VStack의spacing속성을 고려하여, 태그가 존재할 때만 간격 값(8)을 더해줍니다.
태그가 비어있다면 간격을 0으로 처리하여 불필요한 공백을 제거합니다.
// 코드 로직 예시
sheetHeight = fieldHeight + tagsHeight + (tags.isEmpty ? 0 : spacing)이 계산된 값은 .presentationDetents([.height(sheetHeight)]) Modifier에 전달되어 시트의 높이를 즉시 업데이트합니다.
이러한 동적 측정 방식은 사용자 경험(UX) 측면에서 콘텐츠에 딱 맞는 높이를 제공하지만, 기술적인 한계와 고려해야 할 사항이 존재합니다.
- 비동기 업데이트의 복잡성:
뷰 렌더링 도중에 상태(State)를 변경하면 Modifying state during view update 경고가 발생할 수 있습니다.
이를 회피하기 위해 DispatchQueue.main.async를 사용하여 높이 업데이트를 다음 런루프(RunLoop)로 미루게 됩니다.
이로 인해 코드가 다소 복잡해지고 디버깅이 어려워질 수 있습니다.
- sheet 자체의 safeArea:
상단의 표를 보면 알 수 있듯이, 태그 유무에 따라 키보드와 입력 필드 간의 간격(spacing)이 다릅니다.
해결 방법을 찾기 위해 노력했지만, SwiftUI, 혹은 UIKit에서 sheet 내부의 safeArea를 조절하는 방법을 찾지 못해 UI의 부조화가 나타나고 있습니다.
TagEditor에서 sheet의 detents 최적화(Deprecated)
PushNotificationView의 푸시 알람 기록 UNDO 과정-V1
PushNotificationView의 푸시 알람 기록 UNDO 과정-V2
PushNotificationView의 푸시 알람 기록 UNDO 과정-V3(최종)
Publishing 상태 변환에 따른 에러 해결하기
iOS 17 이하에서 모달의 isPresented 관리하기
LPMetadataProvider로 웹페이지 썸네일 가져오기
Todo-리마인더-구현-트러블슈팅
iOS 17 .searchable 포커싱 이슈 해결기
TodoListView 헤더 트러블슈팅-스크롤 조정
TodoListView 헤더 트러블슈팅-내비게이션바
Todo Response 트러블슈팅
Fastlane을 통한 배포 자동화 트러블슈팅
PushNotification·WebPage 삭제 리팩토링과 Swift Testing 적용
푸시 알림 리스트 데이터 최신화 개선하기