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
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Código
  • Novedades de SwiftUI

    Explora las últimas novedades de SwiftUI y descubre cómo pueden mejorar tus apps. Presentaremos un nuevo protocolo de documentos con acceso directo al disco y comparación de diferencias basada en instantáneas para crear apps de alto rendimiento; nuevas API para reordenar el contenido en listas, cuadrículas y secciones; y mejoras en la barra de herramientas, como la prioridad de visibilidad y el comportamiento de minimización automática. También abordaremos las API de presentación ampliadas, incluidas las acciones de deslizamiento en cualquier vista, además de las mejoras en el almacenamiento en caché de AsyncImage y la inicialización diferida del estado para los tipos Observable.

    Capítulos

    • 0:00 - Introducción
    • 2:12 - Aspecto renovado
    • 8:06 - Apps basadas en documentos
    • 15:18 - Presentación e interacción
    • 19:58 - Flujo de datos y rendimiento
    • 27:25 - Próximos pasos

    Recursos

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

    Videos relacionados

    WWDC26

    • Moderniza tu app desarrollada con UIKit
    • Tutorial de programación: Crea potentes funcionalidades de arrastrar y soltar en SwiftUI
  • Buscar este video…
    • 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

  • Videos
  • WWDC26
  • Novedades 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