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 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

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

비디오

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

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • Raise the bar with iPhone Duo

    Discover how to adapt your navigation, toolbars, and tab bars for the unique displays of iPhone Duo. Explore the design principles behind the new bar layout, and learn how to configure custom view representations and manage overflow to build powerful, responsive apps.

    챕터

    • 0:00 - Introduction
    • 0:28 - Why bars move to the side
    • 1:29 - Agenda
    • 2:00 - Opt in to vertical bars
    • 3:09 - Understand the shared bar region
    • 4:29 - Order items in a vertical bar
    • 5:56 - Prepare toolbar content
    • 8:00 - Control the axis of an item
    • 9:00 - Prefer symbol-only items
    • 10:07 - Adapt custom views
    • 11:40 - Manage the overflow menu
    • 13:10 - Prioritize item visibility
    • 14:21 - When to opt out
    • 14:53 - Next steps

    리소스

      • HD 비디오
      • SD 비디오

    관련 비디오

    Tech Talks

    • Prepare your app for iPhone Duo

    WWDC26

    • SwiftUI의 새로운 기능

    WWDC25

    • 새로운 디자인 시스템과 더 친숙해지는 법
  • 비디오 검색…

    안녕하세요, 저는 안나라고 합니다. UI 프레임워크 팀의 엔지니어입니다. 저는 마리아입니다. 애플의 디자인 시스템을 담당하는 휴먼 인터페이스 디자이너입니다. 잠깐, 제가 왜 여기에 있죠? 모든 디자이너는 엔지니어이며, 모든 엔지니어는 디자이너입니다. 훌륭한 앱을 만들려면 이 두 가지를 모두 이해해야 합니다. 오늘 안나와 저는 iPhone Duo에서 바(bar)의 수준을 한 단계 높이는 방법을 알려드릴게요.

    iPhone Duo는 Apple 최초의 멀티 디스플레이 아이폰으로, 사용자에게 그 순간에 가장 적합한 방식으로 자유롭게 사용할 수 있는 자유를 선사합니다. 눈치채셨겠지만, 이 기기는 새롭고 독특한 실루엣을 선보이며 확실히 차별화되어 있습니다. 그리고 그 형태는 중요합니다. 더 넓어진 화면 비율 덕분에 앱은 더 많은 가로 공간을 활용할 수 있습니다. 이 너비를 최대한 활용하고 콘텐츠를 위한 세로 공간을 확보하기 위해, 보통 상단과 하단에 위치하던 컨트롤이 측면으로 이동하며, 이로 인해 접근성도 더 쉬워집니다. 이 새로운 디자인은 외부 디스플레이의 세로 콘텐츠 공간을 극대화합니다. 또한 iPhone Duo를 내부 디스플레이로 펼치거나 가로 모드로 전환해도 컨트롤의 위치는 일관되게 유지됩니다. 하지만 기기를 세로 모드로 펼치면, 더 큰 디스플레이는 수평 바가 있는 익숙한 iPhone 레이아웃으로 돌아갑니다. 기억해 두셔야 할 점은, 이 모든 요소가 동일한 구성 요소이며 단지 다른 레이아웃에 맞춰 조정된 것일 뿐이라는 사실입니다. 이제 그 원리를 이해하셨으니, iPhone Duo에서 훌륭한 바(bar) 사용자 경험을 설계하고 구현할 때 유의해야 할 몇 가지 사항을 알려드리겠습니다.

    먼저, 새로운 축에 적응하고 iPhone Duo에서 바를 세로로 배치하는 방법을 안내해 드리겠습니다. 다음으로, 항목의 순서와 다양한 컨테이너와의 상호작용에 대해 논의하겠습니다. 그 후에는 수직 축에 맞춰 툴바 콘텐츠를 어떻게 조정할 수 있는지 공유해 드리겠습니다. 마지막으로, 오버플로 메뉴를 관리하는 방법을 중점적으로 다룰 것입니다. 하지만 안나, 그 이야기를 시작하기 전에 제가 작업 중이던 앱을 보여드려도 될까요? 물론이죠. 이미 크기 조정이 가능하도록 작업은 마쳤습니다. 하지만 제 바는 여전히 가로로 배치되어 있네요. 제가 뭔가 놓친 게 있을까요?

    알겠어요, 마리아. 앱에 새로운 바 동작을 적용하려면 몇 가지 작업을 수행해야 합니다. 먼저, 최신 SDK를 사용하여 앱을 재빌드하세요. 이제 마리아의 앱은 iPhone Duo를 지원할 준비가 되었습니다. 재빌드 시 활성화되는 다른 동작에 대한 자세한 내용은 “iPhone Duo용 앱 준비하기”를 확인해 주세요. 다음으로, TabView나 NavigationStack과 같은 네비게이션 컨테이너에서 제공하는 바를 사용하고 있는지 확인하세요. SwiftUI에서는 툴바 수정자를 NavigationStack이나 NavigationSplitView와 같은 컨테이너와 함께 사용하세요.

    UIKit에서는 자체 바를 관리하는 UINavigationController와 UITabBarController를 사용하는 것이 좋습니다. 예를 들어, 사용자 정의 UIToolbar를 만드는 대신 뷰 컨트롤러에 툴바 항목을 설정하고 이를 네비게이션 컨트롤러에 배치하세요. 사용자 정의 바를 구축하는 데 사용될 경우, UIToolbar, UINavigationBar 또는 UITabBar와 같은 하위 구성 요소의 콘텐츠는 고려되지 않습니다. 앱에서 바가 수직으로 이동하도록 하는 방법을 알게 되었으니, 이제 바의 콘텐츠가 어떻게 배치되는지에 대해 더 자세히 살펴보겠습니다.

    iPhone Duo는 공유 영역 내에서 네비게이션, 툴바, 탭 바 컨트롤이 공존할 수 있도록 합니다. 이를 이해하는 데 도움이 되는 방법은 90도 회전하여 수직 스택으로 상상해 보는 것입니다. 레이아웃에 따라 이러한 항목들이 다양한 조합으로 포함될 수 있습니다. 여기 ‘메모’ 앱에서는 툴바를 사용하는 레이아웃을, ‘시계’ 앱에서는 탭 바를 포함한 레이아웃을 볼 수 있습니다. 그리고 ‘피트니스’ 앱에서는 툴바와 탭 바를 모두 사용하는 레이아웃을 확인할 수 있습니다. 더 복잡한 레이아웃의 경우, 툴바 항목은 컨테이너가 디스플레이 가장자리를 따라 배치되었을 때만 수직으로 이동할 수 있습니다. 분할 화면에서는 세부 정보 열만 참여합니다. 다른 열의 항목은 수평으로 유지됩니다. 또한 세부 정보 열에는 이미 세로 막대가 있으므로, 혼동을 방지하기 위해 확장 시 인스펙터에 별도의 세로 막대가 표시되지 않습니다. 외부 디스플레이에서 시트에 이미 툴바가 있는 경우, 툴바는 세로로 표시됩니다. 내부 디스플레이에서는 기본적으로 중앙 정렬되며, 항목은 가로로 유지됩니다. preferredPlacement API를 사용하여 위치를 변경할 때, 왼쪽에 배치된 시트에는 세로 막대가 표시되지 않는 반면, 오른쪽에 배치된 시트에는 세로 막대가 표시됩니다. 또한 이 막대는 하드웨어와 정렬되어 있으므로, 오른쪽에서 왼쪽으로 읽는 언어 환경에서도 기기의 동일한 쪽에 위치합니다. 막대 자체는 고정된 상태로 유지되는 반면, 콘텐츠는 막대를 중심으로 조정됩니다.

    요약하자면, 모든 컨트롤의 축을 변경하고 싶은 유혹이 들 수 있지만, 컨트롤을 해당 컨테이너와 연관된 상태로 유지해야 합니다. 수직으로 표시될 때 항목들은 명확한 상하 계층 구조를 유지합니다. 먼저 기존 툴바 구성을 점검하여 컨트롤이 권장 순서를 따르는지 확인하세요. 상단 부분은 ‘뒤로’나 ‘닫기’와 같은 주요 탐색 컨트롤을 배치하고, 그 다음으로 ‘완료’와 같은 눈에 띄는 동작을 배치하세요. 네비게이션 컨트롤러를 사용하는 경우 ‘뒤로’ 버튼이 자동으로 추가됩니다. 사용자 정의 ‘뒤로’ 또는 ‘닫기’ 버튼을 사용하려면 SwiftUI에서 cancellationAction 배치를 활용하세요. 그리고 UIKit에서는 ‘leading’ 항목을 사용하고, `leftItemSupplementsBackButton`이 false(기본값)로 설정되어 있는지 확인하세요. `leftItemSupplementsBackButton`? 도대체 누가 이 API 이름을 지은 걸까요? 저는 아니에요.

    주요 동작의 경우, SwiftUI에서는 `topBarPinnedTrailing` 배치 방식을, UIKit에서는 `pinnedTrailingGroup`을 사용하여 배치하세요. 나머지 항목들은 단일 바로 통합되더라도 상단 및 하단 배치를 시각적으로 구분하는 수직 스페이서를 통해 원래의 그룹 구조를 유지합니다. 그리고 모든 포즈에서 바가 수직으로 배치되는 것은 아니라는 점을 기억하세요. 사용자가 iPhone Duo를 사용할 때 액션이 어디에 있는지 다시 익힐 필요가 없도록 컨트롤 배치를 일관되게 유지하세요. 이제 항목이 어디에 배치되는지 알았으니, 툴바 콘텐츠가 준비되었는지 확인해 봅시다.

    항목을 가로로 배치하는 바에 익숙하실 수도 있습니다. 이제 iPhone Duo는 이를 옆으로 돌려 놓습니다. 항목의 높이가 고정되고 너비는 유연하게 조정되는 가로 바와 달리, 세로 바는 항목의 높이를 유연하게 조정할 수 있고 너비는 고정되어 있습니다. 따라서 세로 바는 아이콘만으로 항목을 표현하는 데 더 적합합니다. 일반적으로 앱은 툴바 콘텐츠에 아이콘과 제목, 두 가지 데이터를 지정합니다. 컨텍스트와 항목에 지정된 내용에 따라 시스템은 표시할 형태를 선택합니다. 기존 상단 및 하단 바에 항목이 표시될 때는, 여기 있는 공유 버튼처럼 아이콘을 우선적으로 표시합니다. 편집 버튼처럼 아이콘이 없는 경우에는 텍스트를 표시합니다. 항목이 오버플로 메뉴로 이동하면 제목과 아이콘을 모두 표시합니다. 수직 바를 사용하더라도 이러한 방식은 변하지 않습니다. 여전히 동일한 콘텐츠를 지정하고 수평 바에 동일한 항목을 배치하면 됩니다. 차이점은 이제 시스템이 콘텐츠가 수직 축에 배치되는 것이 더 적합한지, 아니면 수평 축에 배치되는 것이 더 적합한지를 고려한다는 점입니다. 뒤로 가기 버튼이나 공유 버튼처럼 아이콘이 있는

    항목은 축이 수직으로 변경됩니다. 편집 버튼처럼 텍스트만 있는 항목은 계속해서 수평 축에 남아 있습니다. 이미 SwiftUI 레이블이나 UIBarButtonItem의 속성을 사용하여 제목과 이미지를 설정하고 있다면, 세로 막대를 준비하는 데 이미 한 발 앞서 있는 셈입니다. 일반적으로 항목에 대한 모든 정보를 미리 제공하고, 시스템이 상황에 맞는 적절한 표현 방식을 선택하도록 하는 것이 좋습니다. 즉, 콘텐츠가 이미지라 하더라도 제목을 제공하는 것이 여전히 중요합니다. 수평 바와 마찬가지로, 항목이 오버플로 메뉴나 확장된 형태로 이동할 때마다 시스템은 이 제목을 사용합니다. 기본적으로 SwiftUI와 UKit은 항목이 텍스트만 포함된 것인지, 아니면 텍스트 속의 심볼인지와 같은 콘텐츠를 기반으로 항목을 배치할 위치를 추론합니다.

    이 기본 동작을 조정해야 하는 경우, 새로운 AxisBehavior API를 사용할 수 있습니다. 이 API는 몇 가지 다른 상황에서 사용됩니다. 관련된 항목들은 같은 축에 위치해야 합니다. 흔한 예로, ‘시계’ 앱의 이 편집 버튼처럼 심볼과 텍스트 사이를 전환하는 항목이 있습니다. 이 항목은 이론적으로는 심볼이 세로로 표시될 수 있더라도, 세로 막대에 배치되어서는 안 됩니다. 시스템 편집 버튼을 사용한다면 별도의 조치가 필요 없습니다. 이 버튼은 자동으로 가로 막대에 유지됩니다. 심볼과 텍스트 사이를 전환하는 사용자 정의 항목을 만드는 경우, 이 사용자 정의 선택 버튼처럼 ‘수평 전용 축’ 동작을 사용하세요. 반면, 뷰가 UKit의 사용자 정의 뷰이거나 복잡한 뷰인 경우, 시스템은 이를 수평으로 유지합니다. 오른쪽 상단의 나침반 뷰처럼 사용자 정의 뷰가 세로 방향 표현을 지원하는 경우, ‘세로 선호 축’ 동작을 설정하여 세로 막대에 배치될 수 있도록 하세요.

    텍스트만 포함된 항목이나 텍스트와 이미지를 모두 표시하는 사용자 정의 뷰는 최소화하여 더 많은 콘텐츠가 세로 방향으로 배치될 수 있도록 하세요. 대부분의 경우, 이러한 항목은 심볼 표현을 사용하기에 적합합니다. 예를 들어, 수신함에서 카운트를 인라인으로 표시하는 대신 배지를 사용하면, 텍스트와 심볼을 모두 표시하는 항목을 세로 막대에 자연스럽게 어울리는 심볼 전용 항목으로 바꿀 수 있습니다. 아직 iOS 26에 추가된 배지 API를 사용하지 않고 있다면, 이를 도입하여 모든 기기에서 시스템 표준 배지 모양을 적용하세요. 사용자 정의 뷰에 텍스트가 필요한지 평가하는 유용한 방법은 다음과 같은 질문을 해보는 것입니다. ‘이 텍스트는 단순히 심볼을 보강하는 역할만 하는가, 아니면 독립적인 정보를 전달하는가?’ 텍스트가 단지 보충적인 역할만 한다면, 심볼만으로도 해당 동작을 명확하게 전달할 수 있습니다. 하지만 장바구니 버튼에 표시된 금액과 같이 텍스트에 의미 있는 정보가 포함되어 있다면, 해당 컨트롤을 가로 막대에 유지하는 것이 좋습니다. 마지막으로, 액세서리 막대는 수직 축으로 이동하기보다는 키보드에 계속 연결되어 있어야 합니다.

    사용자 정의 뷰를 수직으로 배치할 수 있도록 준비하려면 약간의 추가 작업이 필요합니다. 항목을 포함시킬 때는 해당 항목이 막대의 고정 너비에 맞거나 수직으로 조정된 레이아웃을 갖도록 해야 합니다. 수직 표시를 위해 조정해야 할 메트릭이 있는지 고려해 보세요. 예를 들어, 이 사용자 정의 액션 패널은 수직으로 표시될 때 다른 콘텐츠를 위한 공간을 더 확보하기 위해 제목을 숨기고 길이를 약간 줄입니다. 특히 사용자 정의 뷰의 경우, 수직 바가 표시될 때 변경 사항을 적용하는 것이 좋습니다. 이를 확인하려면 toolbarVerticalEdge 환경 속성 또는 트레이트를 확인하세요. 콘텐츠 뷰 내에서 또는 항목의 사용자 정의 뷰 내에서 이 값을 확인할 수 있습니다. 이 값은 항목이 수직 축에 배치될 수 있을 때 설정되며, 그렇지 않을 때는 nil이거나 지정되지 않습니다. 수평 막대와 마찬가지로, 수직 막대도 기본적으로 스크롤 가장자리 효과가 적용되지 않습니다. 그러나 ‘투명도 감소’ 접근성 설정이 활성화된 경우 배경이 표시됩니다. 어떤 경우에도 사용자 정의 뷰의 콘텐츠가 가독성을 유지하도록 하십시오. 기본적으로 유연한 스페이서의 수직 축 크기는 0입니다. 반면 고정 스페이서는 계속해서 최소 크기를 유지합니다. 바가 가로이든 세로이든 상관없이, 앱에서 추가적인 간격을 생성해서는 안 됩니다.

    마리아, WWDC25 영상에서 이 내용에 대해 이야기하지 않았나요? 네, 그랬습니다. 시청해 주셔서 감사합니다. 아직 앱의 바를 새로운 디자인으로 업데이트하지 않았거나, 개별 항목을 앞쪽 및 뒤쪽 가장자리를 기준으로 그룹화하지 않았다면, 지금이 바로 그 완벽한 시기입니다.

    마지막으로, 오버플로 관리에 대해 이야기해 보겠습니다. 가로 모드에서 바깥쪽 디스플레이에서는 수직 공간이 적기 때문에 항목이 오버플로되는 경우가 더 잦습니다. 키보드와 같은 다른 UI가 나타나거나, 세로 모드에서 PIP(Picture in Picture)를 사용할 때와 같이 툴바가 오버플로되어야 할 수도 있습니다. 가장 먼저 결정해야 할 사항은 툴바 항목과 탭 바 중 어느 쪽을 더 오래 표시할지입니다.

    이 팟캐스트 화면과 같이 탐색에 중점을 둔 환경에서는 툴바가 먼저 축소되어 주요 목적지에 계속 접근할 수 있도록 합니다. 이것이 기본 동작입니다. 게임 앱의 이 화면과 같이 작업 중심의 환경에서는 자주 사용하는 동작을 유지하기 위해 탭 바가 먼저 축소됩니다. toolbarCompressionBehavior API를 사용하여 각 화면에 대한 앱의 기본 설정을 구성하세요. 이 외에도 툴바에 대해서는 좀 더 세심한 고려가 필요합니다. 관리해야 할 항목이 많아지면, 어떤 항목을 계속 표시할지 우선순위를 정해야 합니다. 앱에 이미 자체 오버플로우 메뉴가 있다면, 해당 동작들을 시스템에서 관리하는 단일 메뉴로 통합하세요. SwiftUI에서는 ToolbarOverflowMenu를, UKit에서는 additionalOverflowItems를 사용하여 이를 구현할 수 있습니다. 또한 기존의 모든 메뉴를 오버플로우로 전환해야 하는 것은 아닙니다. 줄임표(…)는 iPhone에서 표준으로 사용되는 오버플로우 기호입니다. 다른 플랫폼의 기호를 도입하기보다는 이 기호를 해당 용도로만 사용하고, 다른 메뉴에는 고유한 기호를 부여하세요. 적절한 콘텐츠가 더 오래 표시되도록 하려면 시스템에 선호도를 명확히 전달해야 합니다.

    탭 바에 우선순위를 두었거나 툴바가 사용 가능한 공간을 초과하면, 항목들이 오버플로 메뉴로 이동하기 시작합니다. 툴바 표시 우선순위를 통해 어떤 항목이 계속 표시될지 세밀하게 제어할 수 있습니다. 기본적으로 항목은 아래에서 위로 넘쳐나지만, 각 항목에 ‘높음’, ‘낮음’ 또는 ‘사용자 지정’ 우선순위를 지정하여 접히는 순서를 제어할 수도 있습니다. 항목 내에서 그룹별로 우선순위를 지정하기 시작하세요. 그런 다음 필요한 경우 각 그룹 내의 항목에 우선순위를 지정하세요. SwiftUI 및 UIKit의 visibilityPriority API를 사용하여 이 우선순위를 구성하세요. 자세한 내용은 WWDC26의 SwiftUI 새로운 기능을 확인해 보세요. 가시성 우선순위를 할당할 때는 사용자가 가장 자주 접근해야 하는 항목이 무엇인지 고려하세요. 메일의 ‘작성’이나 메모의 ‘새 메모’와 같이 자주 사용되는 동작은 오버플로우 영역으로 이동하는 마지막 순위에 포함되어야 합니다. 마찬가지로, 배지가 표시된 항목과 같이 중요한 상태를 전달하는 컨트롤은 한눈에 파악할 수 있도록 더 오랫동안 표시되어야 합니다. 마리아, 이제 막대가 수직으로 배치되는 이유는 알겠는데, 모든 곳에서 수직으로 배치되어야 할까요?

    대부분의 앱은 이 방식을 적용하기에 적합합니다. 하지만 앱에 따라 이 동작을 비활성화해야 할 경우도 몇 가지 있습니다. 계산기 앱처럼 하단 부분이 무거운 레이아웃을 가진 단일 페이지 앱이라면, 가로 레이아웃을 적용하여 콘텐츠가 완전히 확장될 수 있는지 고려해 보세요. 마찬가지로, 여기 닫기 버튼처럼 단 하나의 항목만 있고 컨트롤이 많은 시트의 경우, 사용 가능한 공간을 줄이지 않도록 세로 막대를 비활성화하는 것을 고려해 보세요. 이를 비활성화하려면 `toolbarVerticalBehavior` 및 `preferredVerticalBarBehavior` API를 사용하세요.

    이 모든 것은 꽤 간단한 질문에서 시작되었습니다. 바가 꼭 상단과 하단에 위치해야만 할까요? 스포일러: 바가 이동했습니다. 옆으로요. 그리 멀리 떨어진 건 아닙니다. 이렇게 하면 컨트롤에 쉽게 접근할 수 있으면서도 콘텐츠가 넉넉하게 느껴집니다. 익숙한 사용자 경험을 그대로 유지하면서도 완전히 새로운 iPhone을 탄생시켰습니다. 앱을 준비하려면, 먼저 최신 SDK로 앱을 빌드해야 합니다. 앱 내의 바를 점검하고 새로운 디자인에 대비했는지 확인하세요. 사용자 정의 항목이 수직으로 배치될 수 있도록 업데이트하세요. 그리고 시스템이 적응할 수 있도록 오버플로 우선순위를 반드시 지정하세요. 다른 건 없나요? 오버플로 메뉴에 있습니다. 곧 뵙겠습니다!

    • 2:24 - Use system containers for vertical bar in SwiftUI

      var body: some View {
          NavigationStack {
              ContentView()
                  .toolbar {
                      ToolbarItem(placement: .bottomBar) {
                          ...
                      }
                  }
          }
      }
    • 2:39 - Use navigation containers for vertical bar in UIKit

      // Content from a custom bars (UINavigationBar, UITabBar, UIToolbar)
      // won't be considered. Prefer UINavigationController 
      // and UITabBarController, which manage their own bars.
      let toolbar = UIToolbar()
      toolbar.items = [...]
    • 5:00 - Place a back or close button

      // SwiftUI
      .toolbar {
          ToolbarItem(placement: .cancellationAction) {
              ...
          }
      }
      
      // UIKit
      navigationItem.leftItemsSupplementBackButton = false
      navigationItem.leadingItemGroups
          = [UIBarButtonItemGroup(...)]
    • 5:24 - Place prominent actions

      // SwiftUI
      .toolbar {
          ToolbarItem(placement: .topBarPinnedTrailing) {
              ...
          }
      }
      
      // UIKit
      navigationItem.pinnedTrailingGroup
          = UIBarButtonItemGroup(...)
    • 8:08 - Set a preferred axis for a custom view

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarItem {
                      ProfileView()
                  }
                  .axisBehavior(.verticalPreferred)
              }
      }
      
      // UIKit
      let item = UIBarButtonItem(customView: ProfileView())
      item.axisBehavior = .verticalPreferred
    • 8:36 - Keep an item in the horizontal bar

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarItem {
                      SelectOrDoneButton()
                  }
                  .axisBehavior(.horizontalOnly)
              }
      }
      
      // UIKit
      item.axisBehavior = .horizontalOnly
    • 8:52 - Allow a custom view go in vertical bar

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarItem {
                      CompassView()
                  }
                  .axisBehavior(.verticalPreferred)
              }
      }
      
      // UIKit
      let item = UIBarButtonItem(customView: CompassView())
      item.axisBehavior = .verticalPreferred
    • 9:27 - Use badges

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarItem(...) {
                      InboxButton()
                          .badge(7)
                  }
              }
      }
      
      // UIKit
      let item = UIBarButtonItem(...)
      item.badge = .count(7)
    • 10:36 - Read the vertical bar edge

      // SwiftUI
      struct ContentView: View {
          @Environment(\.toolbarVerticalEdge) var edge
      
          var body: some View {
              switch edge {
                  ...
              }
          }
      }
      
      // UIKit
      switch traitCollection.verticalBarEdge {
          ...
      }
    • 12:23 - Configure toolbar compression behavior

      // SwiftUI
      var body: some View {
          TabView {
              Tab("Recents", systemImage: "clock") {
                  ContentView()
                      .toolbarVerticalCompressionBehavior(.prefersToolbarItems)
              }
          }
      }
      
      // UIKit
      navigationItem.verticalBarCompressionBehavior = .prefersBarItems
    • 12:43 - Use system overflow menu

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarOverflowMenu {
                      Button("Scan") { ... }
                      Button("Connect") { ... }
                  }
              }
      }
      
      // UIKit
      navigationItem.additionalOverflowItems = UIDeferredMenuElement({ provider in
          provider(self.persistentOverflowItems())
      })
    • 13:21 - Set item visibility priority

      // SwiftUI
      var body: some View {
          ContentView()
              .toolbar {
                  ToolbarItem {
                      Button(...) { ... }
                  }
                  .visibilityPriority(.high)
              }
      }
      
      // UIKit
      let item = UIBarButtonItem(...)
      item.visibilityPriority = .high
    • 14:47 - Disable the vertical bar

      // SwiftUI
      var body: some View {
          NavigationStack {
              ContentView()
                  .toolbarVerticalBehavior(.disabled)
          }
      }
      
      // UIKit
      class MyViewController: UIViewController {
          override var preferredVerticalBarBehavior: UIVerticalBarBehavior {
              .disabled
          }
      }
    • 0:00 - Introduction
    • Anna from UI Frameworks and Maria, a Human Interface Designer on Apple's design system, introduce how to raise the bar for your app's bars on iPhone Duo.

    • 0:28 - Why bars move to the side
    • iPhone Duo's wider aspect ratio gives apps more horizontal space. Controls that normally sit at the top and bottom move to the side, preserving vertical space for content and putting controls within easier reach. Their position stays consistent on the inner display in landscape, and returns to a familiar horizontal layout in portrait.

    • 1:29 - Agenda
    • An overview of what's ahead: orienting bars to a vertical axis, item ordering and how it interacts with containers, tailoring toolbar content for a vertical axis, and managing the overflow menu.

    • 2:00 - Opt in to vertical bars
    • Rebuild your app against the latest SDKs, then use bars provided by navigation containers. In SwiftUI, pair the toolbar modifier with NavigationStack or NavigationSplitView. In UIKit, prefer UINavigationController and UITabBarController over custom UIToolbar, UINavigationBar, or UITabBar instances, whose content isn't considered.

    • 3:09 - Understand the shared bar region
    • Navigation, toolbar, and tab bar controls coexist in a shared region — imagine rotating them 90 degrees into a vertical stack. In split views, only the detail column participates and inspectors don't get their own bar. Sheets behave differently per display, and because the bar is aligned with the hardware it stays on the same side in right-to-left languages.

    • 4:29 - Order items in a vertical bar
    • Keep controls associated with their container and audit your existing configuration. Reserve the top for primary navigation like back or close, followed by prominent actions such as done. Use the cancellation action placement in SwiftUI, or a leading item with leftItemSupplementsBackButton set to false in UIKit. Place prominent actions with topBarPinnedTrailing or pinnedTrailingGroup.

    • 5:56 - Prepare toolbar content
    • Vertical bars have a fixed width and flexible item height, making them better suited to symbol-only items. You still specify the same icon and title, but the system now also considers whether content suits a vertical or horizontal axis: items with an icon go vertical, while text-only items stay horizontal. Always provide a title, since the system uses it in overflow menus and expanded forms.

    • 8:00 - Control the axis of an item
    • The new AxisBehavior API adjusts the system's default placement. Keep related items on the same axis — an item that transitions between a symbol and text, like a custom select button, should use the horizontal-only behavior. Custom or complex views stay horizontal by default; set the vertical-preferred behavior when your view does support a vertical representation.

    • 9:00 - Prefer symbol-only items
    • Minimize title-only items and custom views showing both text and an image so more content can go vertical. A badge can turn a text-and-symbol item into a symbol-only one — adopt the badge API added in iOS 26. Ask whether the text merely reinforces the symbol or carries standalone information; keep controls like a cart button showing a dollar amount in the horizontal bar.

    • 10:07 - Adapt custom views
    • Custom views need to either fit the bar's fixed width or have a vertically adapted layout, and some metrics may need adjusting. Read the toolbarVerticalEdge environment property or trait to detect a vertical bar. Vertical bars have no scroll edge effect by default but do get a background when reduce transparency is enabled. Flexible spacers are zero size vertically, while fixed spacers respect their minimum.

    • 11:40 - Manage the overflow menu
    • Items overflow more often on the outer display in landscape, or when competing UI like the keyboard appears. Decide whether your toolbar items or tab bar stay visible longer — toolbars compress first by default, suiting navigation-focused experiences, while task-oriented apps may compress the tab bar. Consolidate any custom overflow into the system menu with ToolbarOverflowMenu or additionalOverflowItems, and reserve the ellipsis for overflow only.

    • 13:10 - Prioritize item visibility
    • Items overflow from bottom to top by default, but visibility priority gives fine-grained control. Assign high, low, or custom priorities using the visibilityPriority APIs, starting with groups and then items within them. Frequently used actions like Compose or New Note should be among the last to overflow, and controls conveying status such as badged items should remain visible to preserve glanceability.

    • 14:21 - When to opt out
    • Most apps are good candidates for vertical bars, but a single-page app with a bottom-heavy layout like Calculator may let content expand better horizontally, and a sheet with only one control such as a close button may not warrant the reduced space. Use the toolbarVerticalBehavior and preferredVerticalBar behavior APIs to disable it.

    • 14:53 - Next steps
    • Build your app with the latest SDKs, audit your bars for the new design, update custom items so they're ready to be placed vertically, and assign overflow priorities so the system can adapt.

Developer 바닥글

  • 비디오
  • Tech Talks
  • Raise the bar with 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. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침