View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Toutes les vidéos
  • À propos

Plus de vidéos

  • À propos
  • Code
  • Nouveautés de SwiftUI

    Explorez les dernières nouveautés de SwiftUI et voyez comment elles peuvent améliorer vos apps. Nous présentons un nouveau protocole Document doté d'un accès direct au disque et d'un système de comparaison basé sur des instantanés pour concevoir des apps haute performance ; de nouvelles API pour réorganiser le contenu dans des listes, des grilles et des sections ; et des améliorations pour les barres d'outils, notamment la priorité de visibilité et un comportement de réduction automatique. Nous abordons également les nouvelles capacités des API de présentation, comme les gestes de balayage sur n'importe quelle vue, ainsi que les améliorations du cache AsyncImage et l'initialisation différée de l'état pour les types Observable.

    Chapitres

    • 0:00 - Introduction
    • 2:12 - Apparence et expérience utilisateur actualisées
    • 8:06 - Apps basées sur des documents
    • 15:18 - Présentation et interaction
    • 19:58 - Flux de données et performances
    • 27:25 - Étapes suivantes

    Ressources

    • TN3211: Resolving SwiftUI source incompatibilities for State and ContentBuilder
    • State()
    • ContentBuilder
    • Swift Collections on GitHub
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC26

    • Atelier de code : créez de puissantes fonctionnalités de glisser-déposer dans SwiftUI
    • Modernisez votre app UIKit
  • Rechercher dans cette vidéo…
    • 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 {
        // ...
      }

Developer Footer

  • Vidéos
  • WWDC26
  • Nouveautés de SwiftUI
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • 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
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines