Single Trailing Item
오른쪽 상단에 버튼 하나만 있는 최소 구성. 유리 캡슐 하나가 떠 있는 형태.
원래 목차 구조를 그대로 유지하고, 각 항목마다 다섯 가지를 달았습니다:
어느 상황에서 사용하는가 /
이렇게 해야하는 이유 /
TIP 실무 참고 /
적절한 예 실제 앱 기준 좋은 사례 2개 /
잘못된 예 흔한 오용 사례 2개 /
참고 자료 해당 항목의 근거 출처.
각 항목 오른쪽의 미니 프리뷰는 해당 요소가 화면 어디에 놓이는지(파란 하이라이트)를 보여줍니다.
본문은 iOS 26(WWDC25) 기준이며, 그 이후 바뀐 내용은 iOS 27 업데이트 행으로 구분해 반영했습니다 (WWDC26 발표 + iOS 27 베타·보도 기준, 최종 업데이트 2026-07-17). 전체 출처는 참고자료 페이지에 있습니다. 왼쪽 목차를 누르면 해당 항목 페이지로 바로 이동합니다.
아홉 개 케이스는 결국 세 변수의 조합입니다 — 위치(top leading/trailing · principal · bottom), 개수(단일 vs 클러스터), 공간 부족 시 처리(overflow). 순서대로 단순→복잡으로 진행됩니다.
오른쪽 상단에 버튼 하나만 있는 최소 구성. 유리 캡슐 하나가 떠 있는 형태.
왼쪽에 여러 버튼이 한 유리 그룹(cluster)으로 묶이고, 오른쪽엔 단일 버튼.
양쪽 모두 여러 아이템 — 왼쪽 캡슐 하나, 오른쪽 캡슐 하나로 두 개의 독립 그룹.
화면 하단 툴바(.bottomBar)에 아이템 하나. 떠 있는 유리로 표시.
제목이 오는 정중앙 자리(.principal)에 커스텀 컨트롤을 배치. 제목을 대체.
중앙에 핵심 컨트롤 + 오른쪽에 보조 액션 하나. 위 두 패턴의 조합.
trailing에 아이템이 폭보다 많을 때, 시스템이 나머지를 … (overflow) 메뉴로 자동으로 접는 동작.
하단 툴바에 버튼이 아닌 임의의 SwiftUI 뷰(텍스트, 상태 표시, 진행바, 슬라이더 등)를 배치.
leading · principal · trailing · bottom을 한 화면에서 동시에 쓰는 종합 구성.
제목은 "화면이 무엇인지"를 말하는 장치. 선택 기준은 계층 깊이(루트냐 상세냐) × 콘텐츠 밀도 × 제목이 컨트롤이 될 필요가 있는가.
내비바 아래 34pt 대형 제목. 스크롤하면 작은 inline 제목으로 자동 축소.
대형 제목의 크기감을 유지하되 내비바 안(inline 위치)에 고정. 스크롤로 밀려나지 않음. iOS 26 신규.
내비바 중앙의 17pt 작은 제목. 가장 간결한 형태.
inline 제목 + 아이템 5개가 좁은 내비바를 나눠 쓰는 극한 케이스.
제목 옆에 표시(⌄)가 붙고, 제목을 탭하면 메뉴가 열림 (toolbarTitleMenu).
기본 텍스트 대신 커스텀 뷰를 대형 타이틀 자리에 — 로고, 아바타+이름, 특수 서식 등.
이 기능이 존재하는 근본 이유: 툴바가 반투명 유리로 콘텐츠 위에 떠 있기 때문에, 그 밑을 지나가는 콘텐츠와 겹치면 컨트롤이 안 보일 수 있음. 가장자리 효과는 가독성을 지키는 안전장치라서 기본으로 켜져 있습니다. 선택 기준은 하나 — "바 뒤로 지나갈 콘텐츠가 얼마나 복잡한가."
경계 없이 부드럽게 번지는(diffused) 페이드. 콘텐츠가 유리 아래로 은은하게 사라짐.
선명한 구분선으로 딱 잘리는 경계. 콘텐츠 영역과 바 영역이 명확히 분리.
hard 경계 + 툴바 배경을 불투명에 가까운 두꺼운 material로. 가독성 최대 구성.
가장자리 효과를 완전히 끔. 콘텐츠가 아무 처리 없이 바 밑을 그대로 지나감.
배치 기준은 검색의 지위: 이 화면에서 검색이 ① 주인공인가 ② 자주 쓰는 조연인가 ③ 가끔 쓰는 단역인가. iOS 26의 큰 변화 — 검색의 기본 위치가 상단에서 하단으로 이동(reachability).
검색 필드를 툴바에 배치 — iPhone은 하단 유리 캡슐, iPad는 상단 trailing.
.searchable()의 automatic도 iOS 26에선 대체로 이 위치로 갑니다.하단 툴바에서 검색 필드와 다른 버튼이 공존하는 구성.
내비바 제목 아래 서랍에 검색바 — 전통적(iOS 25 이전) 위치. 기본은 스크롤하면 접힘.
서랍 검색바를 스크롤해도 항상 표시 (displayMode: .always).
검색 필드를 툴바 정중앙(principal)에 — 제목 자리를 검색이 차지.
시스템 검색바를 다른 툴바 아이템들과 한 툴바 체계 안에 통합 — 자리 확보·분리·축소를 조합.
텍스트는 콘텐츠 길이를 예측할 수 없다는 게 본질입니다. 다섯 케이스는 전부 "공간은 유한한데 텍스트는 가변"이라는 하나의 문제에 대한 서로 다른 답 — 자른다(limit·truncation), 줄인다(scale), 예약한다(range), 그리고 선택하게 한다(selection).
lineLimit(n) — 텍스트가 차지할 수 있는 최대 줄 수를 고정. 넘치는 내용은 잘림.
주문하신 상품이 오늘 오후에 발송될 예정이며 배송 조회는 주문 내역 화면에서 언제든지 확인하실 수 있습니다.
truncationMode(.head / .middle / .tail) — 잘릴 때 어느 부분을 …로 접을지 선택.
minimumScaleFactor(0.5) (+ lineLimit(1)) — 자르는 대신 글자 크기를 줄여서 공간에 맞춤.
lineLimit(2...4) 범위 지정, lineLimit(3, reservesSpace: true) — 최대뿐 아니라 최소 줄 수·공간 예약까지 제어.
textSelection(.enabled) — 읽기 전용 텍스트를 길게 눌러 선택·복사할 수 있게 허용.
쿠폰 코드는 WELCOME-2026 입니다. 길게 눌러 복사하세요.
핵심 원칙은 하나 — 데이터를 문자열로 직접 조립하지 말 것. 단위·이름·날짜·숫자는 문화권마다 표기 규칙이 다르므로, FormatStyle에 데이터를 주고 표기는 시스템에 맡기는 것이 이 API 군의 존재 이유.
Text(measurement, format: .measurement(width: .wide)) — Measurement 값(길이·무게·온도)을 로케일에 맞는 단위 표기로 자동 변환.
PersonNameComponents + .name(style:) — 사람 이름을 성·이름 구성요소로 다루고 표기 순서는 시스템에 위임.
탭 아이템은 앱 최상위 구조의 라벨입니다. 선택 기준은 두 가지 — 아이콘만으로 의미가 통하는가(라벨 스타일), 사용자를 불러야 할 상태가 있는가(배지).
아이콘 + 한 단어 제목의 표준 탭 아이템. 선택된 탭은 틴트 컬러로 강조.
제목 없이 아이콘만으로 구성된 탭 아이템.
아이템 우상단에 빨간 숫자 배지 (.badge(3)) — 미처리 항목 개수.
숫자 대신 짧은 텍스트 배지 (.badge("NEW")) — 상태형 알림.
탭 수는 앱의 정보 구조 그 자체입니다. 3~5개가 표준 범위 — 그보다 적으면 “탭이 맞는가”, 많으면 “구조가 맞는가”를 물어야 합니다.
탭이 둘뿐인 최소 구조 — 하단 바 전체를 두 목적지가 나눠 씀.
.tabBarMinimizeBehavior(.onScrollDown) — 아래로 스크롤하면 탭바가 작게 접힘, 위로 스크롤하면 복원.
3~5개 표준 범위의 전형적 구성 — 대부분의 앱이 도달하는 균형점.
표준 범위를 넘는 6개 탭 — 시스템이 어디까지 수용하는지 보여주는 한계 케이스.
기준은 화면의 주 작업 — 이동이 주 작업이면 탭바를 유지하고, 소비(읽기·보기)가 주 작업이면 물러나게 합니다.
어느 깊이로 들어가도 탭바가 항상 표시되는 기본 동작.
push된 상세 화면에서 .toolbar(.hidden, for: .tabBar)로 탭바를 숨김.
질문은 하나 — 검색이 “하나의 목적지”인가, “별도의 모드”인가. iOS 26은 후자를 위해 search role(분리 캡슐)을 새로 제공했고, iOS 27(WWDC26)은 이 분리 캡슐 자리를 prominent role로 검색 외 탭에도 개방했습니다.
검색을 일반 탭 중 하나로 배치 — 다른 탭과 동급의 섹션.
Tab(role: .search) — 시스템이 검색 탭을 인식해 다른 탭과 분리된 유리 캡슐(오른쪽)로 배치. iOS 26 신규.
search role + tabBarMinimizeBehavior 조합 — 스크롤 시 탭바는 접히고 검색 캡슐은 축소된 채 잔류.
Tab(role: .prominent) — search role 전용이던 trailing 분리 캡슐 자리를 일반 탭에도 개방. 시스템이 해당 탭에 추가 시각 강조를 적용.
.tabViewBottomAccessory — 탭바 위 층에 상주하는 전역 상태 뷰(미니 플레이어 등). 뮤직 앱 패턴을 시스템 API로 표준화한 iOS 26 신규 기능입니다.
탭 3개 위에 액세서리 뷰가 상주하는 기본 구성 — 탭을 전환해도 액세서리는 유지.
액세서리 + 탭바 최소화 — 스크롤하면 탭바가 접히고 액세서리가 그 자리로 내려앉음(inline 배치).
탭 + search role + 액세서리 + 최소화 — 하단 시스템의 풀 구성.
시트의 핵심 변수는 detent(멈춤 높이)와 모달성 — 화면을 얼마나 차지할지, 그리고 뒤 콘텐츠와의 관계(차단 vs 병행)를 어떻게 설정할지가 다섯 케이스의 전부입니다.
.presentationDetents([.large]) — 화면을 거의 다 덮는 기본 시트. 뒤 화면이 살짝 물러나 보임.
.presentationDetents([.medium]) — 화면 절반 높이에서 멈추는 시트.
.height(250) · .fraction(0.3) — 시스템 2단이 아닌 커스텀 높이의 detent.
[.medium, .large] — detent를 여러 개 선언하고 사용자가 끌어서 단계 전환.
.presentationBackgroundInteraction(.enabled(upThrough: .medium)) — 시트가 떠 있는 동안에도 뒤 콘텐츠를 조작 가능. 딤이 없음.
시트의 형제지만 성격은 반대 — 뒤를 완전히 가리고, 스와이프로 닫을 수 없는 강한 모달입니다. 선택 기준은 “실수로 이탈하면 안 되는 흐름인가”.
.fullScreenCover — 화면 전체를 덮으며, 아래로 스와이프해도 닫히지 않음.
전환은 “이 화면이 어디서 왔는가”에 대한 답입니다 — 출처가 의미 없으면 standard(아래에서), 탭한 요소가 곧 열리는 내용이면 zoom(그 자리에서 확대).
아래에서 위로 올라오는 기본 전환 — 모든 시트의 디폴트.
.navigationTransition(.zoom(sourceID:in:)) — 탭한 요소에서 시트가 확대되어 나오는 전환.
zoom 전환을 full screen cover에 적용 — 썸네일이 화면 전체로 확대.
.safeAreaBar(edge:) — 커스텀 뷰를 “바”로 승격시키는 iOS 26 API. 시스템 바처럼 콘텐츠를 자동으로 인셋시키고 스크롤 가장자리 효과에 참여합니다. overlay(가림)와 safeAreaInset(인셋만)의 상위 호환.
.safeAreaBar(edge: .top) — 커스텀 뷰를 상단 safe area에 배치. 스크롤 콘텐츠는 자동으로 그 아래부터 시작.
상단 safe area bar 안에 타이틀 텍스트를 넣은 커스텀 헤더 구성.
.safeAreaBar(edge: .bottom) — 하단 safe area에 커스텀 바. 콘텐츠 끝이 바 위까지 자동 인셋.
하단 커스텀 바 + hard 가장자리 효과 + 시스템 툴바 아이템이 공존하는 구성.
상·하단 동시에 safe area bar + soft 효과 + 툴바 아이템 — 수직 방향 풀 구성.
safe area는 상하에만 있는 게 아닙니다 — 좌우 가장자리(가로 모드의 노치·베젤)에도 같은 문법이 적용됩니다. edge만 바뀌고 개념(인셋 + 효과)은 동일.
.safeAreaBar(edge: .leading, alignment: .top) + material 배경 — 왼쪽 가장자리 위쪽에 세로 바.
.safeAreaBar(edge: .trailing, alignment: .center) — 오른쪽 가장자리 정중앙에 배치.
material은 색이 아니라 배경과의 관계입니다 — 뒤를 블러·채도 조정으로 비추는 반투명 레이어라서, 같은 material도 배경에 따라 표정이 달라집니다. 이 데모가 “여러 배경 위”를 보여주는 이유.
.ultraThinMaterial ~ .thickMaterial — 뒤 배경을 비추는 두께가 다른 반투명 레이어. 밝은 배경, 사진, 다크모드 어디서든 자동 적응.
material이 “유리”라면 vibrancy는 유리에 새기는 법 — material 위의 콘텐츠가 배경색을 끌어와 렌더링되어, 분리되지 않고 또렷해집니다.
material 위의 텍스트·심볼이 배경색을 혼합해 렌더링되는 효과 — .foregroundStyle(.secondary) 같은 시맨틱 스타일이 material 위에서 자동으로 vibrant해짐.
메뉴는 “요청할 때만 나타나는 UI”의 대표 장치입니다 — 평소엔 버튼 하나의 존재감, 탭하면 전체 선택지. minimization 원칙이 액션 목록에 적용된 형태입니다.
Menu — 버튼을 탭하면 열리는 액션 목록. 아이콘·섹션(Divider)·서브메뉴·role(.destructive)·Toggle/Picker 포함까지 조합 가능.
1~7장 68개 항목의 적절한 예·잘못된 예를 관통하는 원칙은 결국 일곱 가지입니다. 각 원칙마다 판단 기준을 한 문장으로 정의하고, 그 기준을 통과한 적절한 예와 기준을 위반한 잘못된 예를 대조합니다. 괄호 번호는 본문의 해당 항목.
크롬(제목·바·버튼)은 콘텐츠를 돕는 수단이지 주인공이 아님. 안 쓰는 순간에는 접히거나 사라져야 함.
.always (1.4.4 위반) — 대부분의 순간 과업에 기여하지 않는 검색바가 세로 한 줄을 상시 소모 ③ leading·principal·trailing·bottom 전부 채우기 (1.1.9 위반) — "자리가 있으니 채운다"는 기준의 정반대.큰 화면에서 상단은 한 손으로 닿기 어려움. 사용 빈도가 배치 높이를 결정한다는 원칙.
leading=이동 · principal=정체성 · trailing=확정 · bottom=빈도. 그리고 같은 유리 캡슐 = 한 세트. 위치와 묶음이 곧 언어.
Liquid Glass의 투명함은 미학이고, 컨트롤이 읽히는 건 기능. 충돌 시 우선순위는 항상 가독성·접근성.
공간은 유한한데 텍스트 길이는 예측 불가. 잘림·축소·예약 중 무엇을 쓸지는 그 텍스트가 "문장"인지 "값"인지가 정한다.
단위·이름·날짜의 표기 규칙은 문화권마다 다름. 앱은 값만 소유하고 표기는 시스템(FormatStyle)에 위임해야 함.
"\(distance) km" 문자열 조립 (2.2.1 위반) — 표기 규칙(단위계)이 문화권마다 다른데 문자열로 굳혔으니 기준의 두 조건을 모두 위반. 미국 사용자에게 킬로미터를 강요하는 국제화 버그 ② "이름 성" 순서 하드코딩 (2.2.2 위반) — "\(firstName) \(lastName)"은 홍길동을 "길동 홍"으로 표기. 이름 순서는 데이터가 아니라 문화권 규칙인데 앱이 소유해버린 경우.액션의 대상이 화면에 보인다면, 별도 버튼을 만들어 관계를 유추시키지 말고 대상을 직접 조작하게 한다.