-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
iOS vs Android 공용 컴포넌트 비교 문서
목적: Humania 앱의 iOS와 Android 플랫폼 간 공용 컴포넌트를 비교 분석하여 향후 유지보수성과 일관성을 높이기 위한 가이드
📋 문서 개요
이 문서는 Humania 프로젝트의 iOS(SwiftUI)와 Android(Jetpack Compose) 플랫폼에서 사용되는 공용 컴포넌트들을 비교 분석한 결과입니다. 각 컴포넌트의 구현 방식, 사용법, 그리고 플랫폼 간 차이점을 정리하여 향후 기능 추가 및 유지보수 시 참고할 수 있도록 작성되었습니다.
1. 🔘 버튼 컴포넌트
1.1 HMButton (Primary Button)
| 구분 | iOS | Android |
|---|---|---|
| 파일 위치 | Presentation/Component/Common/Button/HMButton.swift |
presentation/component/common/button/HMButton.kt |
| 필수 매개변수 | text: LocalizedStringResourceaction: () -> Void |
text: StringonClick: () -> Unit |
| 선택 매개변수 | type: ButtonType = .primaryisLoading: Bool = falseisDisabled: Bool = falsecornerRadius: CGFloat = 8 |
type: ButtonType = ButtonType.PrimaryisLoading: Boolean = falseisDisabled: Boolean = falsemodifier: Modifier = Modifier |
| 고정 높이 | 56pt (40pt for .none type) |
56dp |
| 코너 반경 | 8pt (사용자 정의 가능) | 8dp (고정) |
| 로딩 표시 | ✅ 내장 ProgressView | ✅ CircularProgressIndicator |
| 버튼 타입 | primary, secondary, secondaryGray, secondaryRed, none | Primary, Secondary, SecondaryGray, SecondaryRed, None |
공통점:
- 동일한 5가지 버튼 스타일 지원
- 로딩 상태 및 비활성 상태 관리
- 일관된 높이와 코너 반경
차이점:
- iOS: 다국화 지원 (
LocalizedStringResource), 커스텀 코너 반경 - Android: Modifier 패턴 사용, 고정 스타일링
사용 위치:
- 폼 제출, 액션 버튼, 주요 CTA 버튼
1.2 HMKeyboardButton (키보드 전용 버튼)
| 구분 | iOS | Android |
|---|---|---|
| 특징 | 키보드 툴바 전용 | 키보드 인터랙션 최적화 |
| 애니메이션 | 기본 SwiftUI 전환 | Spring 애니메이션 적용 |
| 코너 반경 | 8pt | 0dp (키보드 스타일) |
플랫폼별 구현 이유:
- iOS: 키보드 툴바 표준 디자인 준수
- Android: Material Design 키보드 가이드라인 반영
2. 📝 텍스트 입력 컴포넌트
2.1 HMTextField (기본 텍스트 필드)
| 구분 | iOS | Android |
|---|---|---|
| 바인딩 | @Binding<String> |
String + onValueChange 콜백 |
| 플레이스홀더 | LocalizedStringResource |
String |
| 보안 입력 | isSecure: Bool |
isPassword: Boolean |
| 클리어 버튼 | isDeleteButtonPresent: Bool |
isDeleteButtonPresent: Boolean |
| 포커스 관리 | @FocusState 통합 |
커스텀 포커스 로직 |
| 높이 | 48pt | 가변 높이 |
2.2 HMAuthTextField (인증 전용 텍스트 필드)
| 구분 | iOS | Android |
|---|---|---|
| 필드 타입 | 9가지 인증 타입 지원 | 9가지 인증 타입 지원 |
| 비밀번호 토글 | ✅ SecureField/TextField 전환 | ✅ VisualTransformation 사용 |
| 글자 수 제한 | 타입별 자동 적용 | 타입별 자동 적용 |
| 상태 메시지 | LocalizedStringResource? |
String |
| 에러 처리 | isError: Bool |
isError: Boolean |
공통 필드 타입:
- ID 입력
- 비밀번호
- 이전 비밀번호
- 새 비밀번호
- 비밀번호 확인
- 닉네임
- 기계 비밀번호
- 기계 비밀번호 확인
- 소개글
차이점:
- iOS: 포커스 상태에 따른 동적 필드 타입 전환
- Android: VisualTransformation으로 비밀번호 마스킹
3. 🧭 헤더 컴포넌트
3.1 HMBackHeaderWithTitle
| 구분 | iOS | Android |
|---|---|---|
| 제네릭 지원 | Content: View 제네릭 |
@Composable (() -> Unit)? |
| 기본 뒤로가기 | Environment(\.dismiss) 자동 |
명시적 콜백 필요 |
| 높이 | 48pt | 48dp |
3.2 HMHomeHeader
| 구분 | iOS | Android |
|---|---|---|
| 알림 배지 | NavigationLink 통합 | 상태 관리 전용 |
| 로고 표시 | ✅ | ✅ |
3.3 HMBackHeaderWithProgress (iOS 전용)
iOS만 존재하는 이유:
- SwiftUI의 네이티브 진행률 표시 최적화
- iOS 디자인 가이드라인의 진행률 표시 패턴 준수
- Android는 다른 진행률 표시 방식 선호
4. 📱 모달 및 오버레이 컴포넌트
4.1 HMBottomSheet
| 구분 | iOS | Android |
|---|---|---|
| 헤더 타입 | 4가지: titleLeading, titleCenter, titleCenterWithBackButton, none | 4가지: TitleLeading, TitleCenter, TitleCenterWithBackButton, None |
| 높이 설정 | height: CGFloat = 280 |
height: Dp 매개변수 |
| 드래그 해제 | presentationDetents 활용 | isDragDismissEnabled: Boolean |
| 제네릭 콘텐츠 | Content: View |
content: @Composable () -> Unit |
4.2 HMPopup
| 구분 | iOS | Android |
|---|---|---|
| 팝업 타입 | 5가지 (동일) | 5가지 (동일) |
| 커스텀 설정 | PopupConfig 모델 |
PopupType.Custom |
| 버튼 레이아웃 | 수평/수직 자동 | 수평/수직 자동 |
공통 팝업 타입:
- updateMandatory - 필수 업데이트
- updateOptional - 선택 업데이트
- backWarning - 뒤로가기 경고
- deleteAllWarning - 전체 삭제 경고
- custom - 커스텀 설정
4.3 HMToast
| 구분 | iOS | Android |
|---|---|---|
| 타입 | error(Error), errorWithTaskName(String), errorWithMessage(String), success(String) | ToastType.Error, ToastType.Success |
| 자동 해제 | 2초 | 2초 |
| 액션 버튼 | ✅ | ✅ |
5. 🔧 폼 및 입력 컴포넌트
5.1 HMToggle
| 구분 | iOS | Android |
|---|---|---|
| 크기 | 56x28pt | Material3 Switch 기본 |
| 색상 커스텀 | onColor, offColor, thumbColor | Material3 기본 색상 |
| 그림자 | 드롭 섀도우 적용 | Material3 기본 엘레베이션 |
구현 차이점:
- iOS: 커스텀 토글 구현으로 더 세밀한 제어
- Android: Material3 표준 Switch 활용
6. 📋 리스트 컴포넌트
6.1 Exercise 관련 컴포넌트
ExerciseLibraryRow
| 구분 | iOS | Android |
|---|---|---|
| 선택 표시 | 체크 아이콘 | 선택 개수 숫자 표시 |
| 아이콘 표시 | 원형 배경 + 컬러 코딩 | 원형 배경 + 컬러 코딩 |
Android만의 고유 기능:
- 선택 개수 표시: 동일 운동 중복 선택 시 숫자로 표시
- 구현 이유: Android 사용자의 수량 선택 패턴에 최적화
ExerciseLibraryFilterChip
| 구분 | iOS | Android |
|---|---|---|
| 분류 구분 | isBodyPart: Bool |
isBodyPart: Boolean |
| 선택 스타일 | 폰트 굵기 + 색상 변경 | 배경색 + 텍스트 색상 변경 |
6.2 기타 Row 컴포넌트
NotificationRow (iOS 전용)
iOS만 존재하는 이유:
- iOS 알림 UI 패턴에 최적화된 레이아웃
- SwiftUI의 네이티브 삭제 기능 통합
AgreementRow (iOS 전용)
iOS만 존재하는 이유:
- iOS 약관 동의 UI 패턴 준수
- 체크박스와 네비게이션의 분리된 터치 영역 필요
7. 🎨 레이아웃 및 유틸리티 컴포넌트
7.1 HMScreen
| 구분 | iOS | Android |
|---|---|---|
| 패딩 | horizontalPadding: CGFloat = 16 |
horizontalPadding: Dp |
| 중앙 정렬 | isAlignCenter: Bool |
isAlignCenter: Boolean |
| 로딩 오버레이 | ✅ | ✅ |
| 상태바 처리 | 네비게이션 바 숨김 | isStatusBarPaddingNeeded |
7.2 네비게이션 컴포넌트
HMBottomTab (iOS) vs MainTabScaffold (Android)
| 구분 | iOS | Android |
|---|---|---|
| 탭 개수 | 4개 | 3개 |
| 탭 구성 | Home, Exercise Record, Routine, My Page | Home, Routine, MY |
| 선택 상태 | 아이콘 + 텍스트 색상 변경 | 아이콘 + 텍스트 색상 변경 |
| 코너 처리 | 상단 둥근 모서리 + 그림자 | 상단 둥근 모서리 (24dp) |
탭 구성 차이 이유:
- iOS: 운동 기록과 루틴을 분리하여 더 세분화된 네비게이션
- Android: 통합된 접근 방식으로 단순화
7.3 아이콘 시스템
SvgIcon (Android 전용)
Android만 존재하는 이유:
- Coil 이미지 로더와 SVG 최적화
- Material Design 아이콘 시스템과 통합
- iOS는 SF Symbols 시스템 활용
8. 📊 고급 컴포넌트
8.1 HMPicker (Android 전용)
Android만 존재하는 이유:
- Android의 스크롤 기반 선택 UX 패턴
- Material Design Picker 가이드라인 준수
- iOS는 네이티브 Picker 활용
8.2 드래그 앤 드롭 시스템 (Android 전용)
Android만 존재하는 이유:
- Jetpack Compose의 고급 제스처 시스템 활용
- Android 사용자의 드래그 조작 선호도
- 루틴 커스터마이징 기능에 특화
9. 🔧 View Modifiers & Extensions
9.1 iOS 전용 Modifiers
- TextInputLimitModifier: 텍스트 길이 제한
- ToastViewModifier: 토스트 표시
- PopupViewModifier: 팝업 표시
9.2 Android의 Modifier 패턴
- Jetpack Compose의 Modifier 체인 활용
- 더 유연한 조합 가능
구현 철학 차이:
- iOS: ViewModifier 패턴으로 기능 확장
- Android: Modifier 체인으로 스타일 조합
10. 📱 플랫폼별 특화 기능
10.1 iOS 전용 기능들
다국화 시스템
LocalizedStringResource활용- 컴파일 타임 다국화 검증
애니메이션 확장
.mediumSpring // 중간 속도 스프링 애니메이션
.fastSpring // 빠른 스프링 애니메이션Focus State 관리
@FocusState private var focusedField: Field?Environment 통합
@Environment(\.dismiss) private var dismiss10.2 Android 전용 기능들
상태 호이스팅 패턴
val (value, setValue) = remember { mutableStateOf("") }Composition Local
CompositionLocalProvider(LocalFocusManager provides focusManager)리소스 시스템
painterResource(id = R.drawable.icon)11. 🏗 아키텍처 패턴 비교
11.1 컴포넌트 구조
iOS (SwiftUI)
Presentation/Component/
├── Common/ # 공통 컴포넌트
├── Enum/ # 타입 정의
├── Model/ # 설정 모델
├── Row/ # 리스트 행 컴포넌트
└── Chip/ # 칩 컴포넌트
Android (Jetpack Compose)
presentation/component/
├── common/ # 공통 컴포넌트
├── types/ # 타입 정의
├── form/ # 폼 관련
├── row/ # 리스트 행 컴포넌트
└── dragdrop/ # 드래그앤드롭
11.2 상태 관리 패턴
iOS
@State,@Binding,@StateObject@FocusState로 포커스 관리@Environment로 전역 상태
Android
remember,mutableStateOfcollectAsState()로 ViewModel 연결CompositionLocal로 전역 상태
12. 🔍 향후 개선 제안
12.1 공통화 가능한 영역
1. 타입 시스템 통일
// Android
enum class ButtonType { Primary, Secondary, SecondaryGray, SecondaryRed, None }// iOS
enum ButtonType { case primary, secondary, secondaryGray, secondaryRed, none }제안: 케이스 이름을 완전히 통일 (lowerCamelCase vs PascalCase)
2. 매개변수 이름 통일
onClickvsaction→onClick로 통일 제안isDisabledvsisDisabled→ 이미 통일됨 ✅textvstext→ 이미 통일됨 ✅
3. 컴포넌트 네이밍 통일
HMBackHeaderWithTitle→ 양쪽 동일 ✅HMBottomSheet→ 양쪽 동일 ✅HMPopup→ 양쪽 동일 ✅
12.2 플랫폼별 특화 기능 확장
iOS 기능을 Android로 확장
- HMBackHeaderWithProgress: Android에 진행률 헤더 추가
- NotificationRow: Android 알림 리스트 최적화
- AgreementRow: Android 약관 동의 UI 개선
Android 기능을 iOS로 확장
- HMPicker: iOS 커스텀 피커 컴포넌트 개발
- 드래그 앤 드롭: iOS 루틴 편집 기능 향상
- SvgIcon: iOS SVG 아이콘 시스템 통합
12.3 성능 최적화 제안
iOS
@ViewBuilder최적화로 렌더링 성능 향상LazyVStack/LazyHStack더 적극 활용
Android
remember및derivedStateOf최적화LazyColumn/LazyRow아이템 키 관리
13. 📚 컴포넌트 사용 가이드라인
13.1 새 컴포넌트 추가 시 체크리스트
1. 크로스 플랫폼 고려사항
- 동일한 컴포넌트 이름 사용
- 동일한 매개변수 이름 (플랫폼 컨벤션 고려)
- 동일한 기본 동작 보장
- 플랫폼별 최적화 고려
2. iOS 컴포넌트 추가 시
-
LocalizedStringResource사용 -
@FocusState포커스 관리 - Generic
Content: View고려 - ViewModifier 패턴 활용
3. Android 컴포넌트 추가 시
-
Modifier매개변수 추가 - 상태 호이스팅 패턴 적용
-
@Composable함수형 콘텐츠 - Material3 가이드라인 준수
13.2 유지보수 우선순위
높음 (즉시 개선 필요)
- 탭 네비게이션 구조 통일 검토
- 운동 선택 UI 일관성 개선
- 에러 메시지 다국화 통일
중간 (계획적 개선)
- 진행률 표시 컴포넌트 Android 추가
- 드래그 앤 드롭 기능 iOS 추가
- 커스텀 피커 컴포넌트 iOS 개발
낮음 (장기 개선)
- 애니메이션 시스템 통일
- 테마 시스템 확장
- 접근성 기능 강화
14. 📖 결론
Humania 앱의 iOS와 Android 버전은 전반적으로 높은 수준의 컴포넌트 일관성을 보여줍니다. 주요 성과:
✅ 잘 구현된 부분
- 컴포넌트 네이밍: 95% 이상 일관성 유지
- 핵심 기능: 버튼, 텍스트 필드, 모달 등 핵심 UI 요소 통일
- 타입 시스템: ButtonType, TextFieldType 등 완전 동기화
- 사용자 경험: 양 플랫폼에서 동일한 사용 흐름 제공
🔧 개선이 필요한 부분
- 네비게이션 구조: 탭 개수 차이 (iOS 4개 vs Android 3개)
- 플랫폼 특화 기능: 일부 기능의 한쪽 플랫폼 누락
- 세부 동작: 운동 선택 등 일부 인터랙션 차이
🚀 향후 발전 방향
- 단계적 통일: 핵심 컴포넌트부터 순차적 개선
- 플랫폼 특성 존중: 무리한 통일보다는 각 플랫폼 최적화 우선
- 지속적 모니터링: 새 기능 추가 시 크로스 플랫폼 일관성 검증
이 문서를 바탕으로 향후 개발 시 일관성 있는 사용자 경험을 제공하면서도 각 플랫폼의 장점을 살린 개발이 가능할 것입니다.
문서 작성일: 2025년 1월 27일
작성자: Claude Code Assistant
버전: 1.0
다음 리뷰 예정: 2025년 4월