아이폰앱을 아이패드로 대응할때
화면크기 때문에 고려해야할 점에 대해 알아보려합니다
@Environment(\.horizontalSizeClass)
ViewTahtFits
NavigationSplitView
inspector
@Environment(\.horizontalSizeClass)
현재 뷰가 그려지는 가로 폭의 종류를 알려줍니다.
- 개발자가 직접 분기
- 화면 크기, 멀티윈도우 창에 맞는 크기로 알아서 적용
아이폰에서 값은
세로일때 = compact
가로일때 = regular
타입으로 나옵니다.
아이패드에서 값은
세로,가로 풀 사이즈 일때 = regular
멀티윈도우로 사이즈조절시 = compact



비율대로 넓어지는 UI인경우
화면이 넓어지면 2열로 변경되는 대응을 할수있습니다.
struct SizeClassDemo: View {
@Environment(\.horizontalSizeClass) private var hSizeClass
// 현재 상태를 화면에 보여주기 위한 보조 계산 프로퍼티들
private var isRegular: Bool { hSizeClass == .regular }
private var stateText: String { isRegular ? "regular" : "compact" }
private var bannerColor: Color { isRegular ? .blue : .orange }
var body: some View {
VStack(spacing: 16) {
// 현재 horizontalSizeClass 값을 알려주는 상단 배너 (상태별 배경색이 다르다)
banner
// 핵심 분기: 같은 콘텐츠를 폭에 따라 다르게 배치한다.
if isRegular {
// 넓은 화면: 목록 / 상세를 좌우로 나란히 (HStack)
HStack(alignment: .top, spacing: 16) {
listPane
detailPane
}
} else {
// 좁은 화면: 동일 콘텐츠를 위아래로 쌓는다 (VStack)
VStack(spacing: 16) {
listPane
detailPane
}
}
Spacer()
}
.padding()
.navigationTitle("SizeClass 분기")
}
}
ViewTahtFits
공간에 맞는 뷰를 선택합니다.
사용가능한 공간을 측정해, 자식을 위->아래(코드상위치) 순서로 시도하고
넘치지 않고 들어 맞는 첫번째 자식만 렌더링합니다.
- 프레임워크가 알아서 선택(if없음)
- 화면크기, 멀티윈도우 창 대응가능
- 컨테이너 뷰 크기에 대응가능 -> frame 고정시
화면 폭/회전/dynamic type등으로 공간이 달라질때, 코드분기없이 공간에 맞는 레이아웃을 자동으로 선택하고 싶을때 사용




struct ViewThatFitsDemo: View {
// 컨테이너 폭을 직접 조절해 가며 어떤 후보가 선택되는지 관찰한다.
@State private var width: CGFloat = 400
var body: some View {
VStack(spacing: 24) {
// 현재 폭을 숫자로 표시 — 슬라이더를 움직이며 레이아웃 전환 지점을 확인한다.
VStack(spacing: 12) {
Text("컨테이너 폭: \(Int(width)) pt")
.font(.headline)
.monospacedDigit()
Slider(value: $width, in: 0...700)
}
.padding(.horizontal)
ViewThatFits(in: .horizontal) {
// (1) 넓은 레이아웃: 아이콘 + 긴 텍스트 + 버튼 (가장 큰 후보)
HStack(spacing: 12) {
Image(systemName: "wifi")
Text("네트워크에 연결되었습니다 연결되었습니다 연결되었습니다")
.lineLimit(1)
Button("관리") {}
.buttonStyle(.borderedProminent)
}
.candidateStyle(tint: .blue, caption: "넓은 레이아웃")
// (2) 중간: 아이콘 + 짧은 텍스트
HStack(spacing: 8) {
Image(systemName: "wifi")
Text("연결됨")
.lineLimit(1)
}
.candidateStyle(tint: .green, caption: "중간")
// (3) 폴백: 아이콘만 (가장 작은 후보 — 항상 들어맞음)
Image(systemName: "wifi")
.candidateStyle(tint: .orange, caption: "아이콘만")
}
.frame(width: width)
Spacer()
}
.padding(.top, 24)
.navigationTitle("ViewThatFits")
}
}
ViewThatFits vs HorizontalSizeClass
실제 픽셀폭 -> ViewThatFit사용
가로길이가 600이던 1300이던 regular이기 때문에 iPad 풀스크린 세로는 구분 불가능 -> ViewThatFit으로 구분해서 사용
화면 전체 패러다임 전환, 시스템 레벨의 큰 의미 -> HorizontalSizeClass 사용
배타적으로 사용하지않고 큰 구조를 HorizontalSizeClass를 사용하고
그 안에서 디테일은 ViewThatFit으로 처리 하는 식으로 같이사용
NavigationSplitView
2단, 3단 메뉴 옵션이 존재
- side/content/detail 3단 일땐
메뉴가 side, content 2개로 이뤄져있고 메뉴를 뎁스로 하나 더 열 수 있는 구조
- 이때 만약 balanced스타일이라면 content, detail이 화면내에 존재하고 sidebar가 메뉴로 나옴
- compact모드일땐 메뉴 스타일 상관없이 동작방식이 모두 같음
- NavigationSplitViewStyle.prominentDetail: 컨텐츠 사이즈 그대로, 딤처럼 그 위에 사이드바 나옴
- NavigationSplitViewStyle.balanced: 컨텐츠가 좁아지고 사이드바 나옴(컨텐츠와 메뉴가 동등한 레벨)
2단 - balanced 스타일



2단 - prominentDetail 스타일


3단 - balanced 스타일


3단 - prominentDetail 스타일



inspector(isPresented: )
우측 인스펙터 패널
regular 폭(iPad) 에서는 본문 우측에 컬럼으로 붙고
compact 폭(iPhone)에서는 자동으로 sheet형식으로 적응해 표시됨
(아이폰 가로모드에서는 확인가능)
sheet과 배경색도 다르고 가로모드 햇을때 대응도 달라서 같은 용도로 사용하면 안됩니다.



.popover
아이폰
- compact: sheet으로 노출
- regular: sheet으로 노출
아이패드
- compact: sheet으로 변경되서 노출
- regular: 말풍선
.presentationCompactAdaptation(.popover) 사용시
아이폰에서도, 아이패드에서도 compact에서도 모두 말풍선으로 강제적용됨




.presentationDetents
- medium - 화면절반
- large - 전체높이
- fraction() - 화면 비율(0~1)로 지정한 커스텀 높이
- height() - 포인트 단위 고정 높이
presentationDragIndicator - 손잡이 노출옵션
presentationBackgroundInteraction - 배경과 상호작용 옵션
이옵션보다 작은 크기로 펼치면 배경 상호작용은 막힘(배경 딤처리도 달라짐)
ex) option이 medium인 경우 large일 때 배경선택해서 창닫기 가능 (상호 작용되는 경우 뒷배경 회색 딤처리)





'iyOmSd > Title: SwiftUI' 카테고리의 다른 글
| [SwiftUI] CarouselView 근데 이제 UIKit을 곁들인... (0) | 2025.01.29 |
|---|---|
| [SwiftUI] onScrollVisibilityChange 뷰 노출 이벤트 (1) | 2024.11.27 |
| [SwiftUI] Previewable, PreviewModifier 프리뷰 데이터 공유하기 (1) | 2024.11.25 |
| [SwiftUI] WWDC23 Beyond scroll views (0) | 2024.11.23 |
| [SwiftUI] WWDC24 Work with windows in SwiftUI (1) | 2024.11.21 |