본문으로 건너뛰기

iPhone Duo에 맞춰 SwiftUI 앱 레이아웃 조정하기

Adapting your app for iPhone Duo

swiftwithmajid.com

핵심 요약

  1. iPhone Duo는 접힌 상태와 펼친 상태에서 가로 size class가 달라지므로, 화면 크기나 기기 종류가 아니라 size class를 기준으로 레이아웃을 조정해야 한다.
  2. TabView의 sidebarAdaptable 스타일과 NavigationSplitView는 compact·regular 환경에 따라 탐색 구조를 바꾸며, defaultTabBarPlacement로 탭 바의 기본 위치를 지정할 수 있다.
  3. AnyLayout을 사용하면 콘텐츠의 구조적 identity를 유지하면서 세로·가로 레이아웃을 전환할 수 있고, Xcode의 App Resizability skill을 에이전트에 적용할 수도 있다.

도입

iPhone Duo는 크기와 종횡비가 다른 두 디스플레이를 제공한다. 접힌 상태에서는 가로 size class가 compact이고 펼친 상태에서는 regular다. 따라서 화면 경계값이나 기기 종류로 분기하기보다 size class에 따라 앱의 탐색 구조와 콘텐츠 배치를 조정하는 접근이 필요하다. 이미 iPad 레이아웃에 대응한 앱이라면 조정 작업의 큰 부분을 마친 셈이다.

상세 요약

size class로 화면 상태 구분하기

iPhone Duo는 크기와 종횡비가 다른 두 디스플레이를 제공한다. 접힌 상태의 가로 size class는 compact이고, 펼친 상태에서는 regular다. 앱을 iPad 레이아웃에 맞춰 두었다면 적응 작업의 큰 부분을 마친 셈이다.

화면 경계값이나 기기 idiom을 기준으로 분기하지 말고 size class를 관찰해 레이아웃을 조정한다. 원문은 가로·세로 크기 자체보다 compact와 regular라는 환경 구분을 활용하는 방식을 제안한다.

탐색 컴포넌트의 적응 동작

TabView는 .sidebarAdaptable 스타일을 적용하면 regular 가로 size class에서 두 영역으로 구성된 사이드바를 사용하고, compact에서는 일반 탭 뷰로 접힌다.

TabView {
    // tabs
}
.tabViewStyle(.sidebarAdaptable)
.defaultTabBarPlacement(.sidebar)

defaultTabBarPlacement는 탭 바의 기본 위치를 지정한다. iPhone에서는 탭 바가 화면 아래에 있고 위치를 바꿀 수 없지만, iPhone Duo에서는 사이드바에 맞춰 배치할 수 있다.

NavigationSplitView도 size class에 맞춰 표시 방식을 바꾼다. compact에서는 단일 패널 탐색을 표시하고, regular에서는 여러 패널로 전환한다.

AnyLayout으로 콘텐츠 배치 전환

접힌 상태에서 펼친 상태로 바뀔 때 콘텐츠의 배치도 전환할 수 있다. horizontalSizeClass 값을 읽어 compact에서는 VStackLayout, 그 외에는 HStackLayout을 선택하고, 이를 AnyLayout으로 감싼다.

let layout = horizontalSize == .compact
    ? AnyLayout(VStackLayout())
    : AnyLayout(HStackLayout())

layout {
    // your content here
}

AnyLayout을 쓰면 레이아웃을 바꾸면서도 구조적 identity를 잃지 않는다. 원문은 이를 통해 상태 간 전환을 애니메이션으로 처리할 수 있다고 설명한다.

에이전트 활용

원문은 Xcode의 App Resizability skill을 에이전트가 사용할 수 있다고 소개한다. 에이전트에 “Adopt the app to iPhone Duo.”라고 요청하는 방식을 제시한다.

접힌 화면과 펼친 화면을 Simulator에서 점검하는 내용은 iPhone Duo Simulator로 SwiftUI 앱의 레이아웃과 동작 테스트하기에서 이어서 확인할 수 있다.

결론

핵심은 iPhone Duo 전용 UI를 새로 만드는 것이 아니라 compact와 regular size class에 맞춰 기존 탐색과 레이아웃을 구성하는 것이다. TabView와 NavigationSplitView는 size class에 따라 탐색 형태를 바꾸고, AnyLayout은 레이아웃 전환 중에도 뷰의 구조적 identity를 유지한다. 원문은 Xcode의 App Resizability skill을 에이전트에 활용하는 방법도 소개한다.