View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

    • 개요
    • 알아보기
    • Apple Developer Program

    알림 받기

    • 최신 뉴스
    • Hello Developer
    • 플랫폼

    플랫폼 탐색

    • Apple 플랫폼
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    피처링

    • 디자인
    • 배포
    • 게임
    • 액세서리
    • 웹
    • 홈
    • CarPlay
    • 기술

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • AI 및 머신러닝
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 보안
    • Xcode Cloud
    • 커뮤니티

    커뮤니티 탐색

    • 개요
    • Apple과의 만남 이벤트
    • 커뮤니티 이벤트
    • 개발자 포럼
    • 오픈 소스

    피처링

    • WWDC
    • Swift Student Challenge
    • 개발자 이야기
    • App Store 어워드
    • Apple 디자인 어워드
    • 문서

    문서 탐색

    • 문서 라이브러리
    • 기술 개요
    • 샘플 코드
    • 휴먼 인터페이스 가이드라인
    • 비디오

    릴리즈 노트

    • 피처링 업데이트
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • 다운로드

    다운로드 탐색

    • 모든 다운로드
    • 운영 체제
    • 애플리케이션
    • 디자인 리소스

    피처링

    • Xcode
    • TestFlight
    • 서체
    • SF Symbols
    • Icon Composer
    • 지원

    지원 탐색

    • 개요
    • 도움말
    • 개발자 포럼
    • 피드백 지원
    • 문의하기

    피처링

    • 계정 도움말
    • 앱 심사 지침
    • App Store Connect 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

    • 이벤트
    • 뉴스
    • 포럼
    • 샘플 코드
    • 비디오
 

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • Strike a pose with adaptive layouts on iPhone Duo

    Learn how to create responsive, flexible layouts that work great on iPhone Duo. Explore displacement design patterns that keep content visible and reachable as people open and close their iPhone Duo. Discover how to use arrangement views in SwiftUI and UIKit to build split and overlay presentations, and find out how to query reserved regions to tailor layouts around the hinge and cameras.

    챕터

    • 0:00 - Introduction
    • 0:27 - Reserved regions on iPhone Duo
    • 1:29 - Designing around the hinge
    • 2:26 - Displacement patterns
    • 4:00 - Choose where content moves
    • 5:12 - Adapt content to its new region
    • 6:39 - Query reserved regions
    • 7:50 - Division and occlusion regions
    • 8:39 - System containers that adapt
    • 9:20 - Introducing arrangements
    • 11:17 - Build with ArrangementView
    • 12:00 - Configure the split arrangement
    • 13:21 - Use the overlay arrangement
    • 14:39 - Choose between arrangements
    • 16:09 - When not to use an arrangement
    • 16:34 - Next steps

    리소스

      • HD 비디오
      • SD 비디오

    관련 비디오

    Tech Talks

    • Leverage multiple displays and scenes on iPhone Duo
    • Raise the bar with iPhone Duo
  • 비디오 검색…

    안녕하세요, 제 이름은 마리아입니다. 애플의 디자인 시스템에서 일하는 휴먼 인터페이스 디자이너입니다. 저는 해리입니다. UI 프레임워크 엔지니어입니다. 오늘은 iPhone Duo의 독특한 특성에 맞춰 레이아웃을 만드는 방법에 대해 이야기해 보겠습니다. 넓은 화면은 콘텐츠에 새로운 기회를 제공하고, 앱이 화면 형태에 적응할 수 있는 새로운 방법을 열어줍니다.

    iPhone Duo는 여러 개의 디스플레이를 갖추고 있으며, 각 디스플레이마다 고유한 크기 클래스가 있습니다. 이미 크기 조절 기능을 고려하여 디자인하고 계신 분이라면 이 개념이 익숙하게 느껴지실 겁니다. 새로운 하드웨어 기능들도 사용 가능한 공간을 형성하는 데 중요한 역할을 합니다.

    여기에는 힌지와 외부 및 내부 디스플레이에 배치된 두 대의 카메라가 포함됩니다.

    우리는 이를 ‘예약 영역’이라고 부르며, 해리가 나중에 이에 대해 더 자세히 설명할 것입니다. 이 영역들은 레이아웃이 이미 적응하고 있는 다른 영역들과 똑같이 취급하면 됩니다. 예를 들어, iPadOS의 창 제어 요소들처럼 말이죠. 외부 디스플레이의 카메라는 항상 표시되며, 시스템 툴바와 탭 바는 새로운 안전 영역 내에 수직으로 배치됩니다. 더 자세한 내용은 “iPhone Duo로 한 단계 더 높이(Raise the Bar with iPhone Duo)”를 확인해 보세요. 다행히 저도 그 자리에 있을 예정입니다. 내부 디스플레이에서는 인터페이스가 접힘 현상에 맞춰 조정되거나, FaceTime 카메라가 활성화되었을 때 이에 대응하도록 조정될 수 있습니다. 뷰파인더가 사용자 경험의 핵심이라면, 중요한 콘텐츠와 컨트롤을 해당 영역에서 멀리 배치하세요.

    레이아웃에서 힌지를 다루는 방식도 달라집니다. 기기가 책처럼 부분적으로 접혀 있을 때, 디스플레이가 중앙을 따라 휘어지면서 내부 디스플레이가 여러 개의 사용 가능한 영역으로 나뉩니다.

    마리아, 이 책을 발견했어요. 두 페이지에 걸쳐 펼쳐진 이 사진을 한번 보세요. 별로 보기 좋지 않죠? 맞아요. 책등 쪽으로 갈수록 이미지의 일부가 잘 보이지 않아서 더 이상 하나의 연속된 이미지로 인식되지 않아요. 앱에서도 같은 현상이 발생할 수 있을까요? 물론이죠. 접힘선을 가로지르는 콘텐츠와 컨트롤도 매우 유사한 방식으로 작동합니다. 따라서 앱이 이러한 변화에 잘 적응할 수 있도록, iPhone Duo에서 앱이 마치 제자리에 있는 것처럼 자연스럽게 느껴지도록 돕는 일련의 디자인 패턴과 도구를 개발했습니다. 먼저 변위(displacement) 패턴과 그 배후에 있는 몇 가지 디자인 원칙에 대해 설명해 드리겠습니다. 그 다음에는 ‘배치(Arrangements)’라고 부르는 새로운 UI 패턴에 대해 이야기해 보겠습니다. 그럼 시작해 볼까요.

    iPhone Duo를 위한 훌륭한 디자인은 언제 적응해야 할지 아는 데 달려 있습니다. 많은 인터페이스는 예약된 영역을 자연스럽게 우회할 수 있지만, 일부는 ‘변위’라고 부르는 패턴을 통해 보다 의도적인 접근 방식이 필요합니다. 이 패턴은 사용 가능한 공간에 따라 기존 요소의 프레임을 조정하여, 기기가 부분적으로 접혀 있어도 중요한 콘텐츠가 계속 보이게 하고, 접근 가능하며, 가려지지 않도록 합니다.

    일반적인 디자인은 기기가 펼쳐져 있을 때 화면 중앙에 요소를 배치하는 것으로 시작합니다. 기기가 접히면, 해당 요소는 그 목적에 맞는 영역으로 이동합니다.

    저는 단일 요소로 간단히 시작해 보겠지만, ‘디스플레이스먼트’는 버튼에서 전체 컨테이너나 레이아웃의 더 큰 부분에 이르기까지 훨씬 더 광범위하게 적용될 수 있습니다. 콘텐츠에 가장 잘 맞는 적용 범위를 선택하세요. 요소가 독립적으로 적응할 수 있다면, 해당 요소만 따로 이동시키세요. 요소들이 서로 연동되는 경우에는, 그 관계를 유지하기 위해 함께 이동시키세요. 또한 과도한 이동은 피해야 한다는 점을 명심하세요. 요소를 원래 위치에서 멀리 이동시키면 시각적 관계가 약해집니다.

    예를 들어, 앨범에서 사진을 선택할 때, 컨텍스트 메뉴를 뒤쪽 영역에 중앙 정렬하는 대신 두 요소가 함께 이동하여 접힘선을 기준으로 정렬되도록 합니다. 기사, 피드, 문서, 목록과 같은 연속 스크롤 콘텐츠는 위치를 이동시키지 않습니다.

    이러한 경험은 이미 스크롤을 통해 적응되므로, 사용 가능한 영역 간에 이동시키면 연속성이 깨질 수 있습니다.

    콘텐츠의 위치를 이동시킬 때는 그 목적을 기준으로 이동 위치를 결정해야 하며, 콘텐츠가 속해야 할 위치는 기기 사용 방식에 따라 달라질 수 있습니다. 책처럼 부분적으로 접혀 있을 때, 알림과 같은 요소는 뒤쪽 영역으로 이동합니다. 이렇게 하면 기기가 닫히면서 외부 디스플레이에서 경험이 계속될 때, 해당 요소가 표시될 위치에 더 가깝게 유지됩니다. 기기를 테이블 위에 세워 놓았을 때, 두 영역은 서로 다른 종류의 경험을 지원합니다. 상단 영역은 멀리서 보아도 잘 보이는 콘텐츠에 적합합니다. 같은 알림도 이곳으로 이동시켜 쉽게 찾을 수 있도록 할 수 있습니다.

    하단 영역은 상호작용이 가능한 컨트롤에 적합합니다. 미디어 컨트롤과 같은 탭 가능한 요소는 이곳으로 이동하여 터치에 더 안정적인 표면을 제공할 수 있습니다. 그리고 여러 영역이 모두 적합한 경우에는 맥락에 맞는 배치를 우선시하십시오. iPhone에서와 마찬가지로, 검색이 집중 모드에서 활성화된 상태에서는 키보드 위에 표시됩니다. 기기가 펼쳐져 있을 때는 입력란이 제공되는 추가 공간을 활용합니다. 기기가 접히면 너비와 위치가 조정되어 검색 중인 화면 위에 계속 표시됩니다.

    요소가 이동할 위치를 결정했다면, 새로운 환경에 어떻게 적응할지 고려하십시오. 위치와 크기가 가장 흔한 변화이지만, 다른 시각적 속성도 적응할 수 있습니다.

    액션 시트, 알림, 메뉴, 팝오버는 모두 예약된 영역 위에 표시될 수 있는 가벼운 상황 기반 경험입니다. 따라서 주요 목표는 이러한 요소들이 완전히 보이도록 유지하는 것입니다. 시스템은 예약된 영역을 중심으로 구성 요소의 위치를 자동으로 재조정합니다. ‘알림’과 같은 분할 화면 앱에서 시스템은 두 열의 너비를 조정하고 50/50으로 균등하게 분할하여 두 열이 모두 보이도록 유지합니다.

    이 ‘피트니스’ 디자인에서는 기기가 접힐 때 그리드 내 모든 항목이 상호작용 가능한 상태를 유지하고 싶습니다. 힌지 주변의 간격을 늘리면서도 바깥쪽 여백을 유지함으로써 각 컨테이너를 해당 영역 내에 둘 수 있습니다. 이 모든 예시에서 공통적으로 나타나는 점은 이미 존재하는 요소를 이동하거나, 크기를 조정하거나, 재배치한다는 것입니다. 사용자가 iPhone Duo를 어떤 방식으로 사용하든 전체 경험을 누릴 수 있도록 콘텐츠, 기능 및 레이아웃을 계속 이용할 수 있게 하세요. 이제 예약 영역에 적응하는 방법을 알게 되셨을 겁니다. 해리, 개발자들이 알아두어야 할 새로운 API가 있나요?

    좋은 질문이네요, 마리아. 저는 새로운 API만큼 좋아하는 게 없거든요. 사실, 여러분께 소개해 드리고 싶은 새로운 API가 몇 가지 있습니다.

    SwiftUI에서는 GeometryReader나 onGeometryChange 수정자를 통해 GeometryProxy를 사용하여 예약 영역을 조회할 수 있습니다. 지오메트리 프록시의 새로운 reservedRegion 메서드를 사용하여 뷰에서 사용할 수 있는 영역을 가져올 수 있습니다. 예약 영역에는 여러 종류가 있습니다. 여기서 폴드(fold)는 더 큰 영역을 여러 개의 작은 영역으로 나누기 때문에 ‘분할(division)’ 예약 영역을 기반으로 합니다.

    UIKit에서는 UIView에 제공되는 reservedRegion 메서드를 사용합니다. 예약 영역의 frame 속성을 조회하여 이를 자체 레이아웃에 반영할 수 있습니다. 영역은 활성 상태이거나 비활성 상태일 수 있습니다.

    기본적으로 활성 영역만 반환되지만, reservedRegion 메서드의 includeInactive 쿼리 옵션을 사용하여 비활성 영역을 조회할 수도 있습니다.

    iPhone Duo에서 폴드(fold)의 분할 영역은 사용자가 기기를 접었을 때만 활성 상태가 됩니다. 기기가 펼쳐져 있을 때는 비활성 상태이며 너비가 0입니다. 비활성 영역을 활용하여 앱에 대한 고수준의 결정을 내릴 수 있습니다. 예를 들어, 그리드 형태의 레이아웃에서 분할 영역이 존재할 경우, 활성 상태와 관계없이 열 수를 짝수로 유지하는 것이 바람직할 수 있습니다.

    ‘차단 영역(occlusion regions)’이라고 하는 또 다른 종류의 예약 영역이 있습니다. 이 영역들은 영역을 분할하지 않고, 대신 영역을 차단합니다. 이들을 뷰의 경계 내에 있는 더 작은 프레임으로 생각하면 됩니다. iPhone Duo에서 FaceTime 카메라는 차단 영역으로 표현됩니다. reservedRegion 메서드에 오클루전 종류를 전달하여 이를 조회할 수 있습니다. 폴드의 분할 영역과 마찬가지로, 이 영역은 카메라가 활성 상태일 때 활성화되고 비활성 상태일 때 비활성화됩니다.

    고마워요, 해리. 당신은 언제나 제 질문에 대한 답을 알고 계신 것 같아요.

    커스텀 뷰에서 예약 영역을 사용할 생각에 정말 기대가 됩니다. 하지만 시스템 디자이너로서 말하자면, 폴드에 적응하는 우리만의 컴포넌트를 활용하는 것이 훨씬 더 기대됩니다.

    NavigationStacks, NavigationSplitViews, TabViews 등 많은 컴포넌트들을 이미 잘 알고 계실 겁니다. 이러한 시스템 컨테이너를 사용하면 사용자가 앱 전체를 탐색하는 방식에 대한 일반적인 패턴을 활용할 수 있습니다. 또한 List나 ScrollView와 같은 뷰는 콘텐츠를 담는 컨테이너 역할을 합니다.

    “해리, 스플릿 뷰와 비슷한 레이아웃이 있는데, 거기에 포함된 확장 및 축소 동작은 별로 필요 없어요. 대신 사용할 수 있는 다른 게 있을까요?” 와, 마리아, 또 훌륭한 질문이네요. 네, 여러분께 소개해 드릴 또 다른 컨테이너가 있습니다.

    레이아웃 컨테이너는 이러한 내비게이션 및 콘텐츠 컨테이너 사이에 위치합니다. 이 레이아웃 컨테이너는 일련의 규칙에 따라 두 개의 뷰를 배열합니다. 이를 ‘배열(arrangements)’이라고 합니다. 그렇다면 ‘배열’과 ‘규칙’이란 정확히 무엇을 의미할까요? 설명하기 위해 팟캐스트 앱을 열어보겠습니다. 여기서는 iPad에서 팟캐스트 재생을 시작했고, 현재 ‘재생 중’ 뷰를 보고 있습니다. 오른쪽 하단에 대본을 표시해 주는 버튼이 있습니다. 그 버튼을 탭하면 대본 뷰가 나타나며, 이제 레이아웃이 반으로 나뉩니다. iPhone Duo에서 같은 뷰를 표시해 보면, 꽤 비슷합니다. 기기를 접은 후에도 말이죠. iPad의 이 분할 레이아웃은 iPhone Duo에 꽤 잘 적용됩니다.

    하지만 대본 버튼을 다시 탭하면 어떤 일이 일어나는지 주목해 보세요. 대본은 다시 사라지지만, ‘현재 재생 중’ 뷰는 iPad에서처럼 중앙에 정렬되지 않습니다. 대신, 접힌 부분에 의해 정의된 왼쪽 영역에 고정된 상태로 유지됩니다. 마리아가 말했듯이, 이렇게 하면 컨트롤에 쉽게 접근할 수 있고 시야가 가려지지 않습니다. iPhone 듀오를 가로보다 세로가 더 길게 회전시키면, ‘현재 재생 중’과 대본 보기는 분할 레이아웃을 전혀 사용하지 않습니다. 대신, 대본 보기는 인라인 방식으로 표시됩니다.

    따라서 ‘현재 재생 중’ 뷰의 적절한 레이아웃을 결정하려면, 뷰의 가로 및 세로 크기 클래스, 너비와 높이의 종횡비, 활성 분할 영역이 있는지 여부 등 여러 가지 입력 요소를 고려해야 합니다.

    이러한 입력 요소를 바탕으로, ‘현재 재생 중’ 뷰의 레이아웃에 대한 출력 결과를 결정할 수 있습니다. 예를 들어, 뷰를 표시할지 여부와, 표시할 경우 프레임 크기는 어떻게 될지 등을 결정할 수 있습니다. 이러한 입력에서 출력으로 이어지는 기능을 통칭하여 ‘배열(arrangement)’이라고 합니다. 그리고 iOS 27.1에서는 시스템에서 제공하는 배열을 여러분의 앱에서 사용할 수 있습니다. 마리아 님이 앞서 정말 훌륭한 지적을 많이 해주셨는데, 제가 메모를 해둘 걸 그랬네요. 완전히 우연의 일치로, 저도 오디오 메모 앱을 개발하고 있습니다.

    제 앱에서 이 새로운 API를 어떻게 사용할 수 있는지 보여드리겠습니다. 여기 제 NavigationStack이 있습니다. 먼저 스택 안에 ArrangementView를 추가해 보겠습니다. ArrangementView는 주 뷰(primary view)와 보조 뷰(secondary view)를 받습니다. 그래서 현재 재생 중인 오디오 노트에 대한 정보를 표시할 PlayerView와, 현재 노트가 끝난 후 재생될 노트를 표시할 UpNextView를 제공할 것입니다. UIKit에서는 UIArrangementViewController를 사용하여 UINavigationController의 루트 뷰 컨트롤러로 추가하겠습니다. 그런 다음 Player 및 UpNextView 컨트롤러를 ArrangementViewController의 주 뷰 컨트롤러와 보조 뷰 컨트롤러로 설정하겠습니다. arrangementViewStyle 수정자를 사용하여 선호하는 배열을 구성할 수 있습니다.

    기본 스타일은 ‘split’이며, 여기서는 이를 수동으로 지정하겠습니다.

    상상하실 수 있듯이, 'split' 배열은 제공된 경계를 주 뷰와 보조 뷰 사이에 분할합니다.

    기본적으로 뷰의 너비가 높이보다 클 때, 예를 들어 여기에서와 같이 화면 비율이 넓은 iPad에서 사용하거나, iPhone 또는 iPhone Duo에서 유사한 화면 비율을 사용할 때 수평으로 분할됩니다. 기기를 회전하면 뷰의 높이가 너비보다 커지므로 'split' 스타일은 수직으로 분할됩니다. 현재 재생 중인 뷰의 경우, 항상 수평으로만 분할되기를 원합니다. 따라서 split ArrangementStyle의 axes 메서드를 사용하여 분할할 축을 지정하겠습니다. 분할 배열이 특정 축을 따라 분할할 수 없고, 해당 축이 주 축인 경우, 배열 뷰는 단일 뷰만 표시하도록 선택합니다. 여기서는 ArrangementView의 높이가 너비보다 크기 때문에 PlayerView만 표시하도록 선택합니다. 따라서 주 축은 세로이지만, 수평으로만 분할할 수 있습니다. UIKit에서는 UIArrangementViewController의 updateArrangement 메서드를 호출하고, SwiftUI에서 설정된 것과 동일한 수평 축으로 구성된 UISplitArrangement 타입을 사용할 것입니다.

    다음은 분할 배치를 사용한 iPhone Duo의 플레이어 및 ‘다음 재생’ 뷰입니다. 뷰를 배치하기 위한 또 다른 배치를 살펴보고 싶습니다. 이를 오버레이 배열이라고 합니다. 콘텐츠를 나란히 배치하는 것을 선호하는 분할 배열과 달리, 오버레이 배열은 콘텐츠를 서로 위나 아래에 배치하는 것을 선호합니다. 여기서는 배열 뷰를 업데이트하여 오버레이 배열 스타일을 사용하도록 하겠습니다. 이것을 마리아에게 보여주기 전에 마무리 작업을 조금 더 하고 싶어서, 플레이어와 ‘다음 재생’ 뷰의 위치를 바꾸고 접힘 상태를 추가하겠습니다. 결과는 꽤 괜찮네요.

    이제 기기를 접으면, 오버레이 배열은 주 뷰와 보조 뷰를 나란히 배치하려고 합니다. 이렇게 하면 ‘UpNext’ 뷰에 훨씬 더 여유로운 공간이 생기는데, 이 점을 활용하고 싶습니다. 오버레이 배열을 사용할 때는 overlayArrangementZIndex 환경 속성을 조회할 수 있습니다. ‘UpNext’ 뷰에서는 사용자가 기기를 접거나 펼칠 때마다 이 값이 변합니다. 이 값을 활용하여 UpNext 뷰의 접힌 상태와 펼쳐진 상태를 전환하겠습니다.

    UIKit에서는 UIArrangementViewController의 `stateForViewPlacement` 메서드를 호출한 다음, 반환된 상태의 `ZIndex` 속성을 사용하여 주 뷰의 Z 인덱스를 조회할 수 있습니다. 해리, 선택지가 정말 많네요. 한 가지 물어볼 게 있는데요. 이 중에서 어떻게 선택해야 할지 생각해 보셨나요?

    물론이죠. 먼저, 기존 앱의 패턴을 반드시 따르세요. 이미 HStack이나 VStack 같은 컴포넌트를 사용하여 앱의 일부에서 분할형 레이아웃을 구현하고 있다면, ‘분할 배열(split arrangement)’을 사용하는 것을 고려해 보세요. 앱의 일부에서 ZStack과 같은 컴포넌트를 사용하여 오버레이(overlay)와 유사한 레이아웃을 이미 구현하고 있다면, 오버레이 배치를 사용하는 것을 고려해 보세요. 이러한 컴포넌트는 iPhone Duo에 대한 내장 지원을 통해 자연스럽게 각 배치 방식으로 변환됩니다. 의지할 수 있는 기존 패턴이 없다면, 뷰들 사이에 명확한 전경/배경 관계가 있을 때 오버레이 배치를 고려해 보세요.

    예를 들어, 여기 ‘접근성 리더’에서는 컨트롤이 전경에 있고 읽을 수 있는 콘텐츠가 배경에 있습니다. 읽을 수 있는 콘텐츠를 오버레이 위로 스크롤할 수 있으므로, 때때로 일부가 가려져도 괜찮으므로 오버레이 배치를 사용하는 것이 훌륭한 선택입니다.

    콘텐츠 간에 ‘주 콘텐츠-세부 정보’ 관계가 더 뚜렷한 경우에는 분할 배치를 고려해 보세요. 다시 ‘팟캐스트’ 앱으로 돌아가 보면, 대본 뷰는 현재 재생 중인 팟캐스트에 대한 더 자세한 정보를 제공합니다. 두 요소 중 어느 하나도 가려지지 않는 것이 중요하므로, 여기서는 분할 배치를 사용하는 것이 훌륭한 선택입니다. 자, 마리아, 잘 듣고 있었는지 한번 볼까요? 제 오디오 메모 앱에는 어떤 배치를 사용해야 할까요? 흠. '다음 재생 목록'은 플레이어와 배경적인 관계를 맺는 것이 아니라 재생 상태에 대한 더 자세한 정보를 제공하는 것이므로, 분할 ArrangementView를 사용해야 한다고 생각합니다. 맞아요.

    적절한 배치를 선택하는 것도 중요하지만, ArrangementView가 적합하지 않은 경우도 고려해야 합니다. 예를 들어, ArrangementView는 앱에 탐색 인프라를 제공하지 않습니다. 따라서 NavigationSplitView와 같은 탐색 컨테이너를 ArrangementView 안에 배치하는 것은 피하세요. 또한 List나 ScrollView와 같은 뷰의 특성상, 이러한 스크롤 가능한 컨테이너 안에 ArrangementView를 배치하는 것도 피해야 합니다.

    iPhone Duo는 앱을 위한 다양한 새로운 구성을 도입합니다. 앱이 iPhone Duo에 대비할 수 있도록 하려면, 먼저 앱의 중앙 정렬 레이아웃을 점검해 보세요. 이를 2열 레이아웃으로 변경할 수 있는지, 아니면 해당 사용 사례에서 어떤 변위 패턴이 적합한지 고려해 보세요. 표준 시스템 컨테이너와 프리젠테이션을 사용한다면, 별다른 노력 없이도 많은 기능을 활용할 수 있을 것입니다. 그리고 좀 더 맞춤화된 가로 분할 또는 오버레이 레이아웃을 사용하는 경우, 앱이 지원하는 모든 기기에서 이 레이아웃을 처리하기 위해 ArrangementView 사용을 고려해 보세요. 마지막으로, 뷰 내에서 수동으로 레이아웃이 설정된 컨트롤 중 우선순위가 가장 높은 요소를 파악하고, 필요한 경우 ReservedRegions API를 도입하여 자체적인 오프셋을 구현하는 것을 고려해 보세요. 그렇다면 레이아웃 이외의 목적으로 힌지를 사용하는 것은 어떨까요? 제가 만들어 보고 싶은 꽤 멋진 상호작용 아이디어가 하나 있습니다. 재미있겠네요. 기기의 접힘 상태에 반응할 수 있게 해주는 또 다른 API가 있습니다. 자세한 내용은 “iPhone Duo에서 여러 디스플레이와 장면 활용하기”를 확인해 보세요. 적응형 레이아웃을 사용하면 앱이 어떤 자세에서도 세심하게 설계된 듯한 느낌을 줍니다. 사용자 경험을 개선할 때에만 이동, 크기 조정 및 적응이 이루어집니다. 이러한 새로운 가능성들이 열리면서, 여러분이 어떤 앱을 만들지 정말 기대됩니다.

    • 6:46 - Query reserved regions in SwiftUI

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .division)
      }
    • 7:03 - Query reserved regions in UIKit

      // UIKit
      let regions = view.reservedRegions(
        kind: .division)
      
      // Query the frame to incorporate it into your own layout
      let frames = regions.map(\.frame)
    • 7:22 - Include inactive regions

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .division, options: .includeInactive)
      
        let frames = regions.map(\.frame)
        // ...
      }
    • 8:07 - Query occlusion regions

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .occlusion)
      
        let frames = regions.map(\.frame)
        // ...
      }
    • 11:23 - Add an ArrangementView

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
        }
      }
    • 11:26 - Add a UIArrangementViewController

      // UIKit
      let arrangementVC = UIArrangementViewController()
      let navController = UINavigationController(rootViewController: arrangementVC)
      
      let playerVC = PlayerViewController()
      arrangementVC.setViewController(playerVC, for: .primary)
      
      let upNextVC = UpNextViewController()
      arrangementVC.setViewController(upNextVC, for: .secondary)
    • 12:00 - Specify the split arrangement style

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
          .arrangementViewStyle(.split)
        }
      }
    • 12:41 - Restrict the split to one axis

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
          .arrangementViewStyle(
            .split.axes(.horizontal))
        }
      }
    • 13:07 - Update the arrangement in UIKit

      // UIKit
      let arrangementVC = UIArrangementViewController()
      
      // ...
      
      arrangementVC.updateArrangement(.split.axes(.horizontal))
    • 13:26 - Switch to the overlay arrangement

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            UpNextView()
          } secondary: {
            PlayerView()
          }
          .arrangementViewStyle(.overlay)
        }
      }
    • 14:07 - Respond to the overlay Z index

      // SwiftUI
      enum UpNextMinimization {
        case collapsed; case expanded
      }
      
      struct UpNextView: View {
        @Environment(\.overlayArrangementZIndex)
        private var zIndex: Int
      
        var body: some View {
          UpNextList(minimization: minimization)
        }
      
        var minimization: UpNextMinimization {
          zIndex > 0 ? .collapsed : .expanded
        }
      }
    • 14:21 - Read the Z index in UIKit

      // UIKit
      let arrangementVC = UIArrangementViewController()
      
      // ...
      
      let primaryState = arrangementVC.state(for: .primary)
      myModel.minimization = (primaryState?.zIndex ?? 0) > 0
        ? .collapsed : .expanded
    • 0:00 - Introduction
    • Maria, a Human Interface Designer on Apple's design system, and Harry, a UI Frameworks engineer, introduce how to create layouts that adapt to the unique characteristics of iPhone Duo.

    • 0:27 - Reserved regions on iPhone Duo
    • iPhone Duo has multiple displays, each with its own size class, plus hardware features that shape the available space — the hinge and the cameras on the outer and inner displays. These are called reserved regions, and you treat them like any other area your layout adapts to, such as window controls on iPadOS.

    • 1:29 - Designing around the hinge
    • When the device is partially folded like a book, the hinge divides the inner display into multiple usable regions as the display curves through the center. Just as a photo spread across a book's spine stops reading as one continuous image, content and controls that span the fold become harder to see.

    • 2:26 - Displacement patterns
    • Many interfaces flow naturally around reserved regions, while others benefit from displacement — adjusting the frame of existing elements based on available space. Displacement can scope from a single button to an entire container. Move elements independently when they can adapt alone, together when they work as a unit, and avoid excessive movement that weakens visual relationships. Continuously scrolling content like articles and feeds shouldn't displace.

    • 4:00 - Choose where content moves
    • Let purpose guide where content moves, and note that the right destination changes with how the device is used. Partially folded like a book, alerts move to the trailing side, closer to where they'll appear as the device closes. Propped on a table, the top region suits content viewed at a distance while the bottom suits interactive controls. When multiple regions work, keep things contextual.

    • 5:12 - Adapt content to its new region
    • Position and size change most often, but other visual properties adapt too. The system automatically repositions action sheets, alerts, menus, and popovers around reserved regions to keep them fully visible. In a split view like Reminders it keeps both columns visible with an even split, and a grid can preserve outer margins while increasing spacing around the hinge. Throughout, you're moving, resizing, or reorganizing what's already there.

    • 6:39 - Query reserved regions
    • In SwiftUI, query reserved regions with the new reservedRegion method on a GeometryProxy from GeometryReader or the onGeometryChange modifier. In UIKit, use the reservedRegion method on UIView. Query a region's frame to incorporate it into your layout. The fold is backed by a division region, because it divides a larger area into smaller ones.

    • 7:50 - Division and occlusion regions
    • Regions can be active or inactive; only active ones are returned by default, but the includeInactive query option surfaces the rest. The fold's division region is active only when the device is folded, and has zero width when flat — inactive regions still support high-level decisions, like preferring an even number of grid columns. Occlusion regions occlude rather than divide, and represent the FaceTime camera.

    • 8:39 - System containers that adapt
    • Navigation containers like NavigationStack, NavigationSplitView, and TabView provide common navigation patterns, while content containers like List and ScrollView hold your content. Both adapt to the fold for free.

    • 9:20 - Introducing arrangements
    • A layout container sits between navigation and content containers, arranging two views according to a set of rules called an arrangement. Using the Podcasts Now Playing and transcript views as an example, an arrangement is a function of inputs — size classes, the view's aspect ratio, and any active division regions — to outputs, like whether to show a view and what frame it gets. iOS 27.1 makes system-provided arrangements available in your app.

    • 11:17 - Build with ArrangementView
    • An ArrangementView takes a primary and a secondary view — here a player view and an up-next view — and goes inside a NavigationStack. In UIKit, use UIArrangementViewController as the root view controller of your UINavigationController, configuring the primary and secondary view controllers.

    • 12:00 - Configure the split arrangement
    • Set the preferred arrangement with the arrangementViewStyle modifier; the default split style divides its bounds between the primary and secondary views. It splits horizontally when the view is wider than it is tall and vertically when taller. Restrict this with the axes method, and note that when the arrangement can't split along its primary axis it shows only a single view. In UIKit, use the update arrangement method with UISplitArrangement.

    • 13:21 - Use the overlay arrangement
    • Unlike split, the overlay arrangement prefers positioning content above or below, moving to side by side when the device folds. Query the overlayArrangementZIndex environment property to respond as the user folds and unfolds — useful for switching between collapsed and expanded versions of a view. In UIKit, use the state for view placement method on UIArrangementViewController and read the returned state's Z index.

    • 14:39 - Choose between arrangements
    • Follow your app's existing patterns: HStack or VStack layouts translate to the split arrangement, ZStack layouts to overlay. Without an existing pattern, choose overlay when there's a clear foreground/background relationship — as in Accessibility Reader, where partially obscuring scrollable content is acceptable — and split when there's a main/detail relationship, as with the Podcasts transcript where neither view should be obscured.

    • 16:09 - When not to use an arrangement
    • ArrangementViews don't provide navigation infrastructure, so avoid putting navigation containers like NavigationSplitView inside one. Because of how List and ScrollView behave, avoid putting an ArrangementView inside a scrollable container.

    • 16:34 - Next steps
    • Audit your app's centered layouts and consider whether a two-column layout or a displacement pattern fits. Standard system containers and presentations give you a lot of behavior for free. For custom horizontal split or overlay layouts, consider ArrangementView, and adopt the ReservedRegions API for your highest-priority manually laid out controls.

Developer 바닥글

  • 비디오
  • Tech Talks
  • Strike a pose with adaptive layouts on iPhone Duo
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • AI 및 머신 러닝
    • Apple Intelligence
    • 오디오 및 비디오
    • 증강 현실
    • 비즈니스
    • 디자인
    • 배포
    • 교육
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 보안
    • Safari 및 웹
    메뉴 열기 메뉴 닫기
    • 문서
    • 다운로드
    • 샘플 코드
    • 비디오
    • 문서 아카이브
    메뉴 열기 메뉴 닫기
    • 도움말 및 문서
    • 문의하기
    • 포럼
    • 피드백 및 버그 리포트
    • 시스템 상태
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, ID 및 프로파일
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Centers
    • App Store 어워드
    • Apple 디자인 어워드
    • Apple Developer Academy
    • WWDC
    최신 뉴스 읽기 Apple Developer 앱 받기 bilibili, LinkedIn, WeChat, YouTube에서 팔로우하기
    Copyright © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침