View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

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

    알림 받기

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

    플랫폼 탐색

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

    피처링

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

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 머신 러닝 및 AI
    • 보안
    • 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 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

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

비디오

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

더 많은 비디오

  • 소개
  • 요약
  • 코드
  • SwiftUI의 새로운 기능

    SwiftUI에 추가된 최신 기능을 살펴보고, 이러한 기능이 앱을 어떻게 향상할 수 있는지 알아보세요. 고성능 앱 빌드를 위한 직접 디스크 접근과 스냅샷 기반 비교 기능을 갖춘 새로운 Document 프로토콜과 리스트, 그리드 및 섹션의 콘텐츠를 리오더할 수 있는 새로운 API, 가시성 우선순위 및 자동 최소화 동작을 포함한 도구 막대 개선 사항을 소개합니다. 또한 모든 뷰에서의 쓸어넘기기 동작과 AsyncImage 캐싱 개선 사항 및 Observable 유형에 대한 지연 상태 초기화 등 확장된 프레젠테이션 API도 다룹니다.

    챕터

    • 0:00 - Introduction
    • 2:12 - Refreshed look and feel
    • 8:06 - Document-based apps
    • 15:18 - Presentation and interaction
    • 19:58 - Data flow and performance
    • 27:25 - Next steps

    리소스

    • State()
    • ContentBuilder
    • Swift Collections on GitHub
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC26

    • 코딩 실습: SwiftUI에서 강력한 드래그 앤 드롭 빌드하기
    • UIKit 앱 현대화하기
  • 비디오 검색…
    • 3:20 - appearsActive environment value

      struct SidebarFooterView: View {
          @Environment(\.appearsActive) private var appearsActive
      
          var body: some View {
              MyAccountView()
                  .opacity(appearsActive ? 1 : 0.5)
          }
      }
    • 3:34 - Menu icon visibility

      CommandMenu("Stickers") {
          Button { openStore() } label: {
              Label("Store", systemImage: "bag.fill")
                  .labelStyle(.titleAndIcon)
              }
          }
          // Other menu items
      }
    • 5:12 - Prominent tab role

      TabView {
          Tab { EventsTab() }
          Tab { HolidaysTab() }
          Tab { FunTab() }
      
          Tab(role: .prominent) {
              CartTab()
          }
      }
    • 6:15 - Toolbar item visibility and overflow menu

      // Toolbar item visibility priority
      
      StickerPageView()
          .toolbar {
              ToolbarItemGroup {
                  UndoButton()
                  RedoButton()
              }
              .visibilityPriority(.high)
              ToolbarOverflowMenu {
                  ChoosePhotoButton()
                  ExportAsImageButton()
                  ClearAllStickersButton()
              }
              ToolbarItem(placement: .topBarPinnedTrailing) {
                  ShareButton()
              }
          }
    • 7:37 - Minimize toolbar on scroll with toolbarMinimizeBehavior

      // Minimize toolbar when scrolling
      
      ScrollView {
          StickerListView()
      }
      .toolbarMinimizeBehavior(.onScrollDown, for: .navigationBar)
    • 9:47 - Document creation sources with context parameter

      // Use the context to create a document
      
      @main
      struct Stickers: App {
          var body: some Scene {
              DocumentGroupLaunchScene("Create a Sticker Page") {
                  NewDocumentButton("New Sticker Page", source: .blank)
                  NewDocumentButton("Sticker Page from Photo…", source: .photo)
              }
             
              DocumentGroup { /* ... */ }
          }
      }
        
      extension DocumentCreationSource {
          static let blank = Self(id: "blank")
          static let photo = Self(id: "photo")
      }
    • 10:01 - Use the context to create a document

      @main
      struct Stickers: App {
          var body: some Scene {
              DocumentGroupLaunchScene("Create a Sticker Page") {
                  NewDocumentButton("New Sticker Page", source: .blank)
                  NewDocumentButton("Sticker Page from Photo…", source: .photo)
              }
             
              DocumentGroup { document in
                  StickerPageDocumentView(document)
              } { configuration, context in
                  StickerPageDocument(configuration: configuration, context: context)
              }
          }
      }
    • 10:43 - Document app declaration

      @main
      struct Stickers: App {
          var body: some Scene {
              DocumentGroup { /* ... */ }
              WindowGroup { /* ... */ }
          }
      }
    • 11:25 - Implement document writing

      @Observable
      final class StickerDocument {
          // ...
      }
    • 11:34 - Implement document writing: list writable formats

      @Observable
      final class StickerDocument {
          
          static let writableDocumentTypes: [UTType] = [.stickerDocument]
        
          // ...
      }
      
      import UniformTypeIdentifiers
      
      extension UTType {
          static let stickerDocument = UTType(exportedAs: "stickerdocument")
      }
    • 11:45 - Implement document writing: provide snapshot

      @Observable
      final class StickerDocument {
          
          static let writableDocumentTypes: [UTType] = [.stickerDocument]
        
          @MainActor
          func snapshot(contentType: UTType) async throws -> sending PageSnapshot { /* ... */ }
            
          // ...
      }
    • 11:54 - Implement document writing: represent the snapshot

      struct PageSnapshot {
          var background: Image
          var metadata: StickerPlacements
          var stickers: [Image]
      }
      
      struct StickerPlacements { /* ... */ }
    • 12:13 - Implement document writing: provide a DocumentWriter

      @Observable
      final class StickerDocument {
          
          static let writableDocumentTypes: [UTType] = [.stickerDocument]
        
          @MainActor
          func snapshot(contentType: UTType) async throws -> sending PageSnapshot {
              makeSnapshot()
          }
            
          func writer(configuration: sending WriteConfiguration) -> sending Writer {
              Writer(contentType: configuration.contentType)
          }
      }
    • 12:33 - DocumentWriter: Snapshot

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
          
          // ...
      }
    • 12:36 - DocumentWriter: PageSnapshot as Snapshot

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
        
          let contentType: UTType
          
          // ...
      }
    • 12:42 - DocumentWriter protocol implementation

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
        
          let contentType: UTType
          
          nonisolated func write(
              snapshot: sending PageSnapshot, to destination: URL,
              previous: sending PageSnapshot?, progress: consuming Subprogress
          ) async throws {
              // write .stickerDocument
          }
      }
    • 13:18 - Progress reporting during writing

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
        
          let contentType: UTType
          
          nonisolated func write(
              snapshot: sending PageSnapshot, to destination: URL,
              previous: sending PageSnapshot?, progress: consuming Subprogress
          ) async throws {
              // report progress…
              // write .stickerDocument
          }
      }
    • 13:27 - Implement document reading with ReadableDocument protocol

      extension StickerDocument: ReadableDocument {
        
      }
    • 14:35 - Add PNG to supported formats list

      @Observable
      final class StickerDocument: WritableDocument {
        
          static let writableContentTypes: [UTType] = [.stickerDocument, .png]
      }
    • 14:48 - Add content type checks

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
        
          let contentType: UTType
          
          nonisolated func write(
              snapshot: sending PageSnapshot, to destination: URL,
              previous: sending PageSnapshot?, progress: consuming Subprogress
          ) async throws {
              if contentType.conforms(to: .stickerDocument) {
                  // write .stickerDocument
              } else if contentType.conforms(to: .png)
              
          }
      }
    • 14:56 - Writing multiple formats including PNG

      struct Writer<Snapshot>: DocumentWriter {
          typealias Snapshot = PageSnapshot
      
          let contentType: UTType
      
          nonisolated func write(
              snapshot: sending PageSnapshot, to destination: URL, 
              previous: sending PageSnapshot?, progress: consuming Subprogress
          ) async throws {
              if contentType.conforms(to: .stickerDocument) {  
                  // write .stickerDocument
              } else if contentType.conforms(to: .png) {
                  let context = CGContext(/* ... */) 
                  context.draw(/* ... */)
              }
          }
      }
    • 15:58 - Reorderable list with reorderContainer

      List {
          ForEach(stickers) { sticker in
              StickerListItemView(sticker: sticker)
          }
          .reorderable()
      }
      .reorderContainer(for: Sticker.self) { difference in
          difference.apply(to: &stickers)
      }
    • 16:14 - Apply changes to a reorderable list's data source

      import OrderedCollections // from https://github.com/apple/swift-collections
      
      extension ReorderDifference where CollectionID == ReorderableSingleCollectionIdentifier {
          func apply(to values: inout [some Identifiable<ItemID>]) {
              var dictionary = OrderedDictionary(uniqueKeys: values.map { $0.id }, values: values)
              let destinationOffset: Int? = switch destination.position {
              case .before(let destination):
                  dictionary.keys.firstIndex(of: destination)
              case .end:
                  nil
              }
              dictionary.move(keys: sources, to: destinationOffset ?? values.endIndex)
              values = dictionary.values.elements
          }
      }
    • 16:48 - Reorderable grid with LazyVGrid

      LazyVGrid {
          ForEach(stickers) { sticker in
              StickerListItemView(sticker: sticker)
          }
          .reorderable()
      }
      .reorderContainer(for: Sticker.self) { difference in
          difference.apply(to: &stickers)
      }
    • 18:12 - Swipe actions on List

      List {
          ForEach(stickers) { sticker in
              StickerListItemView(sticker: sticker)
                  .swipeActions {
                      DeleteButton(sticker: sticker)
                  }
          }
      }
    • 18:15 - Swipe actions on any view

      ScrollView {
          LazyVStack {
              ForEach(stickers) { sticker in
                  StickerListItemView(sticker: sticker)
                      .swipeActions {
                          DeleteButton(sticker: sticker)
                      }
              }
          }
      }
      .swipeActionsContainer()
    • 18:54 - Confirmation dialog with item binding

      struct StickerCanvasView: View {
          var stickers: [Sticker]
          @State private var stickerToDelete: Sticker?
      
          var body: some View {
              ZStack {
                  ForEach(stickers) { sticker in
                      PlacedStickerView(sticker: sticker)
                          .contextMenu {
                              // ...
                          }
                  }
              }
              .confirmationDialog(
                  "Delete?", item: $stickerToDelete
              ) { sticker in
                  DeleteStickerButton(sticker)
              }   
          }
      }
    • 19:35 - Alert with item binding

      struct StickerCanvasView: View {
          var stickers: [Sticker]
          @State private var stickerToDelete: Sticker?
      
          var body: some View {
              ZStack {
                  ForEach(stickers) { sticker in
                      PlacedStickerView(sticker: sticker)
                          .contextMenu {
                              // ...
                          }
                  }
              }
              .alert(
                  "Delete?", item: $stickerToDelete
              ) { sticker in
                  DeleteStickerButton(sticker)
              }   
          }
      }
    • 21:18 - AsyncImage with URLRequest and custom URLSession

      @Observable class StickerStore {
          static let imageSession: URLSession = {
              let config = URLSessionConfiguration.default
              config.urlCache = URLCache(
                  memoryCapacity: 64 * 1024 * 1024,
                  diskCapacity: 256 * 1024 * 1024)
              return URLSession(configuration: config)
          }()
      }
      
      ForEach(pets) { pet in
          AsyncImage(request: URLRequest(
              url: pet.imageURL,
              cachePolicy: .returnCacheDataElseLoad)
          )
      }
      .asyncImageURLSession(StickerStore.imageSession)
    • 23:08 - @State converted to macro for lazy initialization

      @Observable class StickerStore { }
      
      struct StickerStoreView: View {
          // store is now lazily initialized, only
          // created once for the lifetime of the view
          @State private var store = StickerStore()
      
          var body: some View {
              // ...
          }
      }
    • 23:48 - @State macro init assignment error

      struct StickerPageView: View {
          @State private var page = StickerPage()
          let title: String
          
          init(title: String) {
              self.page = StickerPage(title: title) // Variable 'self.title' used before being initialized
              self.title = title
          }
          
          var body: some View {
              // ...
          }
      }
    • 24:02 - Fixed @State macro init assignment error

      struct StickerPageView: View {
          @State private var page: StickerPage // Removed default value to fix error
          let title: String
          
          init(title: String) {
              self.page = StickerPage(title: title)
              self.title = title
          }
          
          var body: some View {
              // ...
          }
      }
    • 26:07 - @ContentBuilder

      @ContentBuilder
      func stickerLibraryView() -> some View {
        // ...
      }
    • 0:00 - Introduction
    • This video covers the refreshed Liquid Glass look and feel, new document-based app APIs, presentation and interaction improvements, and data flow and performance enhancements.

    • 2:12 - Refreshed look and feel
    • Apps automatically adopt the updated Liquid Glass appearance on 2027 OS releases without code changes. Covers interactive Liquid Glass elements, the inactive window appearance on iPadOS, toolbar customization with overflow menus and pinned placements, minimize-on-scroll behavior, and guidance for building resizable apps using size classes.

    • 8:06 - Document-based apps
    • Expanded document APIs for SwiftUI apps, including the new DocumentCreationSource API for custom new-document flows, performance improvements for reading and writing large documents, and first-class support for direct document URL access via the FileDocument and ReferenceFileDocument protocols.

    • 15:18 - Presentation and interaction
    • New reorderable container APIs let users drag to reorder items in any container — List, LazyVGrid, and on watchOS for the first time. Also covers swipe actions on arbitrary views beyond List, and item binding-driven confirmation dialogs.

    • 19:58 - Data flow and performance
    • AsyncImage now supports standard HTTP caching by default, with new APIs for custom URLRequest and URLSession configurations. The @State property wrapper is converted to a macro, making class initialization lazy to prevent redundant allocations — back-ported to iOS 17, macOS 14, and aligned releases.

    • 27:25 - Next steps
    • Key takeaways and recommended next steps: build in Xcode 27 to see the updated Liquid Glass look in your app, adopt the new Document APIs for document-based apps, and explore the SwiftUI agent skills.

Developer Footer

  • 비디오
  • WWDC26
  • SwiftUI의 새로운 기능
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • Apple Intelligence
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • 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 Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    최신 뉴스 읽기.
    Apple Developer 앱 받기.
    Copyright © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침