
-
Novedades de UIKit
Moderniza tu app con las últimas API en UIKit, que incluyen soporte mejorado para la barra de menú, seguimiento automático de observaciones, un nuevo método de actualización de UI y mejoras en las animaciones. También mencionaremos cómo puedes incluir escenas SwiftUI en tu app UIKit y explorar símbolos SF, selectores de color HDR y más.
Capítulos
- 0:00 - Introducción
- 0:59 - Nuevo sistema de diseño
- 2:29 - Contenedores y adaptabilidad
- 3:21 - La barra de menú
- 9:58 - Mejoras arquitectónicas
- 10:21 - Seguimiento automático de observaciones
- 12:33 - Nuevo método de actualización de la IU
- 15:45 - Mejoras en las animaciones
- 17:45 - Actualizaciones de escenas
- 18:55 - Compatibilidad con colores HDR
- 20:38 - Notificaciones Swift
- 21:20 - Migrar a un ciclo de vida basado en escenas
- 22:40 - Compatibilidad de OpenURL con URL de archivos
- 23:17 - SF Symbols 7
- 25:13 - Próximos pasos
Recursos
Videos relacionados
WWDC25
- Conoce el nuevo sistema de diseño
- Crea una app de UIKit con el nuevo diseño
- Haz que tu app UIKit sea más flexible
- Mejora el diseño de tu app para iPad
- Novedades de SF Symbols 7
WWDC24
WWDC23
WWDC21
-
Buscar este video…
Hola. Te doy la bienvenida a “Novedades de UIKit”. Soy Dima, gerente de ingeniería del equipo de UIKit. Desde iOS y iPadOS hasta tvOS, visionOS y Mac Catalyst, UIKit sigue siendo la base de las apps, ahora con aún más mejoras. Primero, explicaré la compatibilidad de UIKit con el nuevo sistema de diseño. Luego, hablaré de las mejoras para que el contenido de tu app se adapte sin problemas a distintos dispositivos y formas de pantalla. Después presentaré las nuevas API de UIKit para la barra de menús, el conocido elemento de macOS que llega a iPadOS. Analizaré los principales avances de arquitectura de UIKit y mencionaré los fundamentos clave. Por último, explicaré las mejoras que incorporamos a la estructura general. El nuevo sistema de diseño presenta un aspecto renovado para los materiales y controles del sistema. La base es el nuevo material: Liquid Glass. Es translúcido, dinámico y animado con efectos, como reflejos especulares y refracción. Desde barras y campos de búsqueda hasta alertas, ventanas emergentes y vistas divididas, los componentes estándar de UIKit se renovaron con el nuevo material.
Las transiciones de navegación ahora son fluidas e interrumpibles, por lo que la app ofrece una mayor capacidad de respuesta.
Los usuarios pueden comenzar a interactuar con el contenido sin esperar a que finalice la animación.
Para adaptar tu IU al nuevo diseño, presentamos nuevas herramientas, como la vista de extensión de fondo, que permite que el contenido aparezca debajo del gran panel de vidrio de la barra lateral sin perder la continuidad visual.
También hay un material de vidrio para tus propios componentes personalizados y el nuevo efecto de borde de desplazamiento para que el contenido desaparezca a medida que se desplaza por debajo de los paneles de vidrio, lo que mejora la legibilidad de los botones de la barra y otros controles.
Para obtener una guía práctica completa sobre cómo actualizar el diseño de tus apps de UIKit, ve el video “Crea una app de UIKit con el nuevo diseño”. Para conocer más sobre el nuevo diseño, consulta “Conoce el nuevo sistema de diseño”. Ahora, hablaré de las mejoras para que el contenido de tus apps se adapte sin problemas a distintos dispositivos y formas de pantalla. En iOS 26, UISplitViewController es compatible con inspectores de primera clase. Un inspector brinda detalles adicionales del contenido seleccionado. Por ejemplo, Vista Previa usa un inspector para mostrar metadatos junto a la foto en la columna secundaria.
Ahora también puedes cambiar el tamaño de las columnas arrastrando los separadores del controlador de vista dividida. Con el puntero, su forma se adaptará para indicar las direcciones en las que se puede cambiar el tamaño de una columna. Para obtener más información sobre las mejoras en los controladores de vista de contenedor y repasar conceptos generales de diseño, como márgenes de diseño y áreas seguras, ve el video “Tu app de UIKit más flexible”. En cuanto al menú: con iOS 26, el iPad tiene la barra de menús de macOS. Ahora, al deslizar el dedo desde la parte superior, aparece el menú completo de la app, incluso sin un teclado físico. Es una excelente manera de acceder rápido a la funcionalidad de la app.
La barra de menús admite todas las funcionalidades del menú: imágenes, submenús, secciones de texto, marcas de verificación y más. Se deberían ver todos los comandos de la app, incluso aquellos sin funciones rápidas de teclado. Además, mantiene visibles los comandos no disponibles, pero desactivados, para que los usuarios aún puedan descubrir todo lo que la app puede hacer.
Las apps aún usan UIMenuBuilder para personalizar los menús principales y, en iOS 26, UIKit presenta varias API nuevas para crear barras de menús aún mejores. Comenzaré con la configuración del sistema del menú principal. Esta API permite que las apps personalicen qué comandos del sistema se proporcionan inicialmente en el menú principal. Cuando usas la API de configuración, la app se incorpora a elementos de menú prediseñados y localizados adicionales, como el nuevo comando para mostrar u ocultar inspectores. Te permite indicar de antemano qué elementos incluir u omitir. También puedes configurar y diseñar en detalle grupos individuales de elementos, por ejemplo, optimizar los comandos de búsqueda para las necesidades de la app. Por último, incluye previamente un bloque UIMenuBuilder para agregar elementos personalizados, lo que permitirá que la app y sus extensiones compartidas usen el mismo código para definir las funciones rápidas de teclado compatibles. Este es un ejemplo de cómo usar una configuración del sistema del menú principal. Primero, creo un objeto de configuración. Luego, especifico qué comandos quiere mi app en el menú principal de forma predeterminada. Por ejemplo, indicaré la compatibilidad con los comandos de impresión del sistema.
No usaré ciertos comandos predeterminados, como el nuevo comando para mostrar u ocultar el panel del inspector. La configuración me permite especificar estilos comunes para los comandos predeterminados, como convertir los comandos de búsqueda del sistema en un solo elemento de búsqueda. Esto es ideal para apps de fotos o música, en las que la búsqueda se centra más en el contenido que en el texto. Por último, puedo establecer la configuración en el sistema del menú principal para que se cree con el conjunto inicial de elementos preferidos. También puedo proporcionar opcionalmente un controlador de compilación, que se ejecutará en lugar de buildMenuWithBuilder. El controlador proporciona acceso a UIMenuBuilder, que se actualizó en iOS 26 con métodos prácticos más potentes, un rendimiento más rápido y diagnósticos mejorados.
Ten en cuenta que al establecer una configuración se volverá a crear la barra de menús. Lo ideal es que tu app establezca la configuración solo una vez y lo antes posible, como en application(_:didFinishLaunchingWithOptions:). iOS y macOS 26 presentan acciones y menús estándar adicionales en la barra de menús. performClose se asigna a Cmd-W y cierra la escena de ventana de forma predeterminada, pero también puedes hacer que cierre otras cosas en la app, como las pestañas de un navegador web. El comando de menú “Nuevo a partir del Portapapeles” permite crear documentos a partir del contenido del Portapapeles, sin activar una alerta de Pegar. El nuevo menú Elemento que se incorporó en iOS 26 es un buen lugar para colocarlo. Las acciones estándar para alinear el texto y mostrar u ocultar la barra lateral y el inspector ahora también están expuestas para que las apps las personalicen. De forma predeterminada, las funciones rápidas de teclado se repiten cuando se mantienen presionadas las teclas, pero puedes personalizar ese comportamiento configurando la propiedad repeatBehavior en UIKeyCommand.
Esta propiedad también se puede configurar por cada respondedor usando validateCommand. Esto es muy importante para acciones destructivas, como presionar la tecla suprimir para eliminar un correo electrónico, de modo que no se activen accidentalmente de forma reiterada. En algunos casos, partes de la barra de menús deben mostrar contenido dinámico según el elemento enfocado o una escena de ventana. Por ejemplo, las apps de navegación como Safari pueden mostrar el historial del perfil de navegación actual en el menú Historial.
Para eso, usa el nuevo elemento de menú diferido basado en el enfoque, que completa los elementos de la cadena de respondedor. Al diseñar el menú principal, crea un UIDeferredMenuElement usando el enfoque y asígnale un identificador para diferenciarlo. Luego, colócalo en el menú principal.
Cuando es necesario cumplir con el elemento diferido, UIKit recorre la cadena de respondedor hasta que encuentra un respondedor que pueda contribuir con elementos. En este ejemplo, el controlador de vista del navegador anula providerForDeferredMenuElement para proporcionar elementos de historial para el perfil actual.
Comprueba el identificador del elemento diferido para el elemento browserHistory y proporciona un proveedor para cargar elementos del menú del historial. Los elementos diferidos basados en el enfoque son una buena forma de mantener la barra de menús actualizada con comandos sin teclas, sin necesidad de realizar rediseños costosos en el sistema del menú principal. Además de los elementos personalizados de la app, el sistema proporciona varias entradas de menú automáticamente. La app tiene una función rápida de teclado para abrir los ajustes en la app Configuración y, para las apps basadas en documentos, el menú Abrir recientes se completará con documentos recientes. El sistema también complementa el menú Ventana con comandos de mosaico, incluida una lista de todas las escenas abiertas de la app. Completa el título de cada escena para ayudar a los usuarios a diferenciarlas. Por último, algunas cosas a tener en cuenta cuando creas la barra de menús. Para las apps de UIKit, las barras de menús definidas en los guiones gráficos ya no son compatibles. Las apps no se iniciarán con menús en los guiones gráficos, por lo que es necesario implementarlas mediante programación.
También debes asegurarte de que la funcionalidad de la app sea accesible sin la barra de menús, ya que esta no siempre estará presente. Para obtener más información sobre cómo crear una excelente barra de menús para tu app, ve “Mejora el diseño de tu app para el iPad”. Para obtener una descripción general del menú principal de UIKit, consulta “Lleva tus apps para el iPad al siguiente nivel”. Seguimos evolucionando UIKit con nuevas funcionalidades para patrones modernos, mejores prácticas y una mayor interoperabilidad con SwiftUI. iOS 26 no es la excepción. Mencionaré nuevas y increíbles mejoras de arquitectura. La primera gran mejora es la compatibilidad integrada con objetos Swift Observable en UIKit.
UIKit ahora incluye Swift Observation: en métodos de actualización como layoutSubviews(), rastrea automáticamente cualquier Observable al que hagas referencia, conecta dependencias e invalida las vistas correctas (no se requiere setNeedsLayout manual). Para implementarlo en iOS 18, agrega la clave UIObservationTrackingEnabled a Info.plist. En iOS 26, está activado de forma predeterminada. Veremos un par de ejemplos de seguimiento automático de observaciones en acción.
Aquí, tengo un controlador de vista de lista de mensajes que contiene un UILabel que indica mensajes no leídos.
Contiene un objeto de modelo Observable con dos propiedades: un valor booleano que controla si se muestra el estado y la cadena de estado. En viewWillLayoutSubviews(), uso el modelo observable para actualizar el alfa de la etiqueta para mostrarla u ocultarla y establecer su texto. En el primer diseño, UIKit completa la etiqueta y, gracias al seguimiento automático de observaciones, registra las dependencias en showStatus y statusText. Cualquier cambio en esas propiedades invalida la vista y vuelve a ejecutar viewWillLayoutSubviews(), manteniendo la etiqueta sincronizada sin código adicional. Este es otro ejemplo del uso de objetos Observable con UIKit, que destaca los beneficios del seguimiento automático de observaciones al configurar celdas en un UICollectionView. Cada celda de la lista cuenta con un ListItemModel observable que contiene un ícono, un título y un subtítulo. Dentro de la devolución de llamada del proveedor de celda, saco de la cola una celda, tomo su modelo y asigno un configurationUpdateHandler. Debido a que este controlador admite el seguimiento de observaciones, UIKit establece automáticamente dependencias en cualquier objeto Observable que use dentro de él.
En el controlador, completo y aplico una configuración de contenido de lista utilizando el modelo de elemento de lista observable, y listo. Si se realiza un cambio en las propiedades del modelo mientras la celda está visible, UIKit vuelve a ejecutar el controlador y actualiza la celda. Con la incorporación del seguimiento automático de características y observaciones, UIKit ahora incluye un método de actualización de propósito general para ofrecer esas funcionalidades.
Presentamos un nuevo método, updateProperties(), tanto para UIView como para UIViewController.
Se ejecuta justo antes de layoutSubviews(), pero es independiente: permite invalidar propiedades sin forzar el diseño y viceversa, para evitar pasos adicionales y obtener actualizaciones más detalladas.
updateProperties() complementa, no reemplaza, layoutSubviews(). Úsalo para completar contenido, aplicar estilos o configurar comportamientos.
Realiza un seguimiento automático de cualquier Observable que leas, y puedes activarlo manualmente mediante setNeedsUpdateProperties(). Veamos un ejemplo concreto del uso de este nuevo método.
Aquí tengo un objeto BadgeModel Observable que almacena la cantidad que se muestra en una vista de insignia. El controlador de vista para el elemento de botón de barra cuenta con un BadgeModel.
Dentro de updateProperties(), uso la nueva API de insignias en el elemento del botón de la barra y extraigo la cantidad directamente del modelo. Ahora, cada vez que cambia el objeto del modelo Observable, se genera updateProperties() y se ejecuta y se actualiza la insignia.
Al usar updateProperties() para configurar la vista en lugar de layoutSubviews(), evito volver a ejecutar el código en eventos no relacionados, como cambiar el tamaño, eliminar trabajo innecesario y mejorar el rendimiento. Para entender mejor cómo updateProperties() se adapta a otros métodos de actualización, veremos cómo funciona el paso de actualización de UIKit.
Esta es una ilustración de cómo UIKit actualiza las vistas antes de mostrarlas en la pantalla. Lo primero es el paso de diseño. UIKit recorre la jerarquía de vistas de arriba hacia abajo, actualiza las características de cada vista y, luego, ejecuta layoutSubviews(). Si ese paso hace que otras vistas requieran diseño, el paso de diseño se repite hasta que todo esté diseñado.
Una vez que se establece el diseño, UIKit realiza el paso de visualización, ejecuta el método de dibujo en cada vista y lo repite hasta que ya no sea necesario mostrar todas las vistas. Una vez finalizados ambos pasos, se puede renderizar el siguiente fotograma y mostrarlo en la pantalla.
Y así es como se integra la nueva devolución de llamada updateProperties(). Durante el paso de diseño de arriba hacia abajo, UIKit ejecuta updateProperties() directamente después de actualizar las características y justo antes de layoutSubviews(). Puedes pensar que layoutSubviews() se divide en dos etapas: primero se actualizan las propiedades y, luego, se aplica la lógica de diseño habitual. Dado que la colección de características se actualiza antes de que se ejecute updateProperties(), puedes leerla allí de forma segura. Como siempre precede a layoutSubviews(), puedes invalidar el diseño dentro de él y el paso de diseño se ejecutará inmediatamente después.
Para complementar la nueva funcionalidad de seguimiento de observaciones y el nuevo método updateProperties(), mejoramos el funcionamiento de las animaciones en UIKit.
Antes de comenzar, repasaremos cómo funciona una actualización manual en iOS 18 y anteriores. En una clausura de animación de UIView, primero se establecen los nuevos valores en los objetos Observable y, luego, se ejecuta layoutIfNeeded() en las vistas que dependen de esos objetos. Ambos pasos son necesarios porque el primero provoca una invalidación y el segundo realiza la actualización y crea animaciones. El mantenimiento manual de las dependencias de propiedades y vistas es propenso a errores y puede generar demasiadas o muy pocas actualizaciones o animaciones. iOS 26 tiene una nueva opción de animación para UIViews denominada flushUpdates. Cuando está activada, UIKit aplica las actualizaciones pendientes justo antes de que comience la animación y de nuevo cuando finaliza, por lo que ya no es necesario ejecutar layoutIfNeeded(). Para que flushUpdates funcione, solo realiza cambios de estado invalidantes dentro de la clausura de la animación. Veamos un ejemplo de cómo utilizar flushUpdates. Primero, incluye flushUpdates como una opción para animar UIView y, luego, realiza cambios en el objeto Observable dentro de la clausura. Cualquier vista que use ese objeto Observable en un método de actualización realizará automáticamente la actualización necesaria. flushUpdates no se limita a las animaciones impulsadas por Observable.
Este es un ejemplo de su uso para animar automáticamente los cambios de restricciones de diseño. En la clausura de flushUpdates, establezco una nueva constante para una de las restricciones existentes y también activo y desactivo otras restricciones. Las vistas dependientes se animan automáticamente en sus nuevas posiciones y tamaños. Ahora explicaré cómo logramos que usar SwiftUI y UIKit en la misma app sea más sencillo. Las escenas de SwiftUI ahora son compatibles con las apps de UIKit mediante un nuevo protocolo de delegado. Esto permite la adopción gradual de SwiftUI y también que las apps de UIKit usen espacios y volúmenes inmersivos en visionOS.
Imagina una app de meditación que incluye una escena de jardín zen: en una ventana 2D estándar del iPhone y iPad, y como un espacio inmersivo en visionOS. Presento ese espacio inmersivo implementando el nuevo protocolo UIHostingSceneDelegate con una escena raíz de SwiftUI.
El uso de un delegado de escena de alojamiento es igual que el de cualquier otro delegado. Configura el tipo de delegado en UISceneConfiguration cuando se conecte una nueva escena.
Puedes solicitar mediante programación una escena de SwiftUI particular al delegado de alojamiento con su identificador.
En este ejemplo, solicito el espacio de jardín zen inmersivo. Por último, te mostraré algunas mejoras generales de UIKit: empecemos por las mejoras en el renderizado HDR. Con iOS 26, HDR ya no es solo para imágenes: los colores se procesan de la misma forma, por lo que puedes acentuar tu interfaz de usuario o brindar nuevas experiencias.
UIColor ahora te permite especificar un color SDR base más un valor de exposición y ajustar automáticamente su brillo a las capacidades de la pantalla. Aquí, creo un color HDR rojo con su exposición establecida en dos veces y media el blanco máximo del SDR. Ahora también puedes activar la selección de color HDR en UIColorPickerViewController y UIColorWell. Para ello, establece una exposición máxima en un valor guiado por las capacidades de renderizado de la app. Aquí configuro la exposición lineal máxima del selector de color para que sea el doble del blanco máximo del SDR.
En iOS 18, UIImageView convierte de forma inteligente HDR en SDR, lo que garantiza que el contenido clave de la IU se destaque. En iOS 26, este comportamiento se traslada al video, y tu propio contenido personalizado también puede participar. Usa la nueva característica UITraitHDRHeadroomUsage para monitorear cuándo el contenido HDR debe volver a SDR. Para obtener más información sobre HDR, consulta los videos “Usa HDR para brindar experiencias de imágenes dinámicas en tu app” y “Compatibilidad con imágenes HDR en tu app”.
A partir de la API NSNotification.Name, UIKit en iOS 26 ahora representa cada notificación como un tipo exclusivo de NotificationCenter.Message. Esto proporciona un valor tipado para registrar observadores y obtener detalles de eventos. Este es un ejemplo de cómo ajustar el diseño cuando aparece el teclado: me registro para el tipo de notificación keyboardWillShow y, luego, en el controlador, extraigo la duración de la animación y el cuadro del teclado directamente del mensaje. Por último, animo las restricciones usando esos valores, ¡sin necesidad de búsquedas de información de usuario ni conversiones manuales! Con cada versión, la evolución continua de UIKit te brinda API modernas e increíbles para las mejores prácticas actuales. A medida que las adoptas, vamos desestimando los métodos anteriores.
Con la adopción de UIScene, tus apps son portátiles y muy flexibles, por lo que dejamos de lado muchas API centradas en UIApplication.
Las devoluciones de llamadas UIApplicationDelegate anteriores y UIApplicationLaunchOptionKeys ya no se aplican, y solo permanece el inicializador init(windowScene:) para UIWindow. Cualquier otro inicializador queda obsoleto. En la versión posterior a iOS 26, cualquier app de UIKit creada con el último SDK deberá usar el ciclo de vida UIScene. De lo contrario, no se iniciará.
Adopta siempre el ciclo de vida UIScene, ¡no solo en apps con varias ventanas! Para obtener información sobre cómo hacerlo, lee la nota técnica: “Migración al ciclo de vida basado en escenas de UIKit”. Para obtener más información sobre cómo maximizar la flexibilidad de tu app, incluidas las nuevas API que te ayudarán a migrar desde UIRequiresFullScreen, consulta el video “Tu app de UIKit más flexible”.
Las apps que usan distintos tipos de documentos con frecuencia necesitan iniciar visores externos. En iOS 26, el método openURL existente ahora acepta URL de archivos, de modo que puedes transferir documentos que no son compatibles de forma nativa con tu app. Si existe una app predeterminada para ese tipo de archivo, el sistema la abre y envía tu URL. En caso contrario, openURL muestra un valor falso, lo que te permite gestionar la reserva, por ejemplo, mediante un controlador de vista previa de vista rápida.
Se mejoró SF Symbols en iOS 26. SF Symbols 7 permite dibujar símbolos, con dos nuevos efectos. Draw Off, al igual que el efecto Disappear, usa la animación de dibujo para ocultar un símbolo. Draw On, al igual que Appear, muestra un símbolo oculto al dibujarlo.
Los símbolos ahora pueden admitir el dibujo de variables, un nuevo modo para valores variables. De esta forma, se dibujan valores arbitrarios en una ruta, como para este indicador de progreso. También puedes usarlo con la transición automática de contenido de símbolo para animar a través de valores variables.
Las transiciones de reemplazo mágico también pueden realizar animaciones de dibujo especiales entre ciertos símbolos. Por ejemplo, esta transición entre el símbolo de círculo y el símbolo de marca de verificación rellena ahora llena el círculo y dibuja la marca de verificación. Las nuevas animaciones de dibujo son muy útiles para los botones, por lo que UIKit tiene una nueva API para adoptar fácilmente las transiciones de contenido de símbolos en UIButton.
Usa la nueva propiedad symbolContentTransition en UIButton.Configuration para especificar una transición de contenido de símbolo, como reemplazar. Cuando el símbolo del botón cambia, por ejemplo, cuando cambia su estado de selección, UIKit realiza la transición. SF Symbols 7 también presenta otras capacidades, como la nueva opción de modo de representación de color. Las apps pueden especificar Degradado para colorear sus símbolos con degradados generados automáticamente en lugar de colores planos.
Para aprender a personalizar completamente el dibujo y los degradados, ve “Novedades de SF Symbols 7”. Para repasar cómo usar los efectos de símbolos para la animación, consulta “Anima símbolos en tu app”.
¿Qué sigue? Compila tu app usando el SDK de iOS 26. Comprueba cómo responde tu app al nuevo diseño y mejora las IU y el estilo para que coincidan con la nueva estética. Usa contenedores estándar, como UISplitViewController y UITabBarController, para ofrecer diseños flexibles. Implementa los menús de tu app con las nuevas API de menú. Adopta el método updateProperties y el seguimiento de observaciones para optimizar el código y mejorar el rendimiento. ¡Gracias! Quiero ver cómo usas estas mejoras para que tus apps sean aún más poderosas y fáciles de usar.
-
-
4:56 - Main menu system configuration
// Main menu system configuration var config = UIMainMenuSystem.Configuration() // Declare support for default commands, like printing config.printingPreference = .included // Opt out of default commands, like inspector config.inspectorPreference = .removed // Configure the Find commands to be a single "Search" element config.findingConfiguration.style = .search
-
5:39 - Main menu system build configuration
// Main menu system configuration // Have the main menu system build using this configuration, and make custom additions. // Call this early, e.g. in application(_:didFinishLaunchingWithOptions:), and call it once UIMainMenuSystem.shared.setBuildConfiguration(config) { builder in builder.insertElements([...], afterCommand: #selector(copy(_:))) let deleteKeyCommand = UIKeyCommand(...) builder.replace(command: #selector(delete(_:)), withElements: [deleteKeyCommand]) }
-
7:01 - Keyboard shortcut repeatability
// Keyboard shortcut repeatability let keyCommand = UIKeyCommand(...) keyCommand.repeatBehavior = .nonRepeatable
-
7:43 - Focus-based deferred menu elements (App Delegate)
// Focus-based deferred menu elements extension UIDeferredMenuElement.Identifier { static let browserHistory: Self = .init(rawValue: "com.example.deferred-element.history") } // Create a focus-based deferred element that will display browser history let historyDeferredElement = UIDeferredMenuElement.usingFocus( identifier: .browserHistory, shouldCacheItems: false ) // Insert it into the app’s custom History menu when building the main menu builder.insertElements([historyDeferredElement], atEndOfMenu: .history)
-
8:06 - Focus-based deferred menu elements (View Controller)
// Focus-based deferred menu elements class BrowserViewController: UIViewController { // ... override func provider( for deferredElement: UIDeferredMenuElement ) -> UIDeferredMenuElement.Provider? { if deferredElement.identifier == .browserHistory { return UIDeferredMenuElement.Provider { completion in let browserHistoryMenuElements = profile.browserHistoryElements() completion(browserHistoryMenuElements) } } return nil } }
-
10:54 - Using an Observable object and automatic observation tracking
// Using an Observable object and automatic observation tracking @Observable class UnreadMessagesModel { var showStatus: Bool var statusText: String } class MessageListViewController: UIViewController { var unreadMessagesModel: UnreadMessagesModel var statusLabel: UILabel override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() statusLabel.alpha = unreadMessagesModel.showStatus ? 1.0 : 0.0 statusLabel.text = unreadMessagesModel.statusText } }
-
11:48 - Configuring a UICollectionView cell with automatic observation tracking
// Configuring a UICollectionView cell with automatic observation tracking @Observable class ListItemModel { var icon: UIImage var title: String var subtitle: String } func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) let listItemModel = listItemModel(for: indexPath) cell.configurationUpdateHandler = { cell, state in var content = UIListContentConfiguration.subtitleCell() content.image = listItemModel.icon content.text = listItemModel.title content.secondaryText = listItemModel.subtitle cell.contentConfiguration = content } return cell }
-
13:27 - Using automatic observation tracking and updateProperties()
// Using automatic observation tracking and updateProperties() @Observable class BadgeModel { var badgeCount: Int? } class MyViewController: UIViewController { var model: BadgeModel let folderButton: UIBarButtonItem override func updateProperties() { super.updateProperties() if let badgeCount = model.badgeCount { folderButton.badge = .count(badgeCount) } else { folderButton.badge = nil } } }
-
16:57 - Using the flushUpdates animation option to automatically animate updates
// Using the flushUpdates animation option to automatically animate updates // Automatically animate changes with Observable objects UIView.animate(options: .flushUpdates) { model.badgeColor = .red }
-
17:23 - Automatically animate changes to Auto Layout constraints with flushUpdates
// Automatically animate changes to Auto Layout constraints UIView.animate(options: .flushUpdates) { // Change the constant of a NSLayoutConstraint topSpacingConstraint.constant = 20 // Change which constraints are active leadingEdgeConstraint.isActive = false trailingEdgeConstraint.isActive = true }
-
18:07 - Setting up a UIHostingSceneDelegate
// Setting up a UIHostingSceneDelegate import UIKit import SwiftUI class ZenGardenSceneDelegate: UIResponder, UIHostingSceneDelegate { static var rootScene: some Scene { WindowGroup(id: "zengarden") { ZenGardenView() } #if os(visionOS) ImmersiveSpace(id: "zengardenspace") { ZenGardenSpace() } .immersionStyle(selection: .constant(.full), in: .mixed, .progressive, .full) #endif } }
-
18:28 - Using a UIHostingSceneDelegate
// Using a UIHostingSceneDelegate func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let configuration = UISceneConfiguration(name: "Zen Garden Scene", sessionRole: connectingSceneSession.role) configuration.delegateClass = ZenGardenSceneDelegate.self return configuration }
-
18:41 - Requesting a scene
// Requesting a scene func openZenGardenSpace() { let request = UISceneSessionActivationRequest( hostingDelegateClass: ZenGardenSceneDelegate.self, id: “zengardenspace")! UIApplication.shared.activateSceneSession(for: request) }
-
19:18 - HDR color support
// Create an HDR red relative to a 2.5x peak white let hdrRed = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0, linearExposure: 2.5)
-
19:50 - HDR color picking
// Support picking HDR colors relative to a // maximum peak white of 2x colorPickerController.maximumLinearExposure = 2.0
-
20:06 - Mixing SDR and HDR content
// Mixing SDR and HDR content registerForTraitChanges([UITraitHDRHeadroomUsageLimit.self]) { traitEnvironment, previousTraitCollection in let currentHeadroomLimit = traitEnvironment.traitCollection.hdrHeadroomUsageLimit // Update HDR usage based on currentHeadroomLimit’s value }
-
20:54 - Adopting Swift notifications
// Adopting Swift notifications override func viewDidLoad() { super.viewDidLoad() let keyboardObserver = NotificationCenter.default.addObserver( of: UIScreen.self for: .keyboardWillShow ) { message in UIView.animate( withDuration: message.animationDuration, delay: 0, options: .flushUpdates ) { // Use message.endFrame to animate the layout of views with the keyboard let keyboardOverlap = view.bounds.maxY - message.endFrame.minY bottomConstraint.constant = keyboardOverlap } } }
-
24:26 - Using a symbol content transition to automatically animate symbol updates
// Using a symbol content transition to automatically animate symbol updates var configuration = UIButton.Configuration.plain() configuration.symbolContentTransition = UISymbolContentTransition(.replace)
-
-
- 0:00 - Introducción
Obtén información sobre las mejoras de UIKit en iOS, iPadOS, tvOS, visionOS y Mac Catalyst. Este video abarca el nuevo sistema de diseño, contenedores y adaptabilidad, API para la barra de menús en iPadOS y Mac Catalyst, avances arquitectónicos centrales y mejoras generales de las estructuras.
- 0:59 - Nuevo sistema de diseño
El nuevo sistema de diseño incluye Liquid Glass: un material translúcido y dinámico que renueva los componentes estándares de UIKit y mejora las transiciones de navegación. UIKit también tiene una nueva API para incorporar Liquid Glass en su interfaz de usuario personalizada.
- 2:29 - Contenedores y adaptabilidad
iOS 26 mejora “UISplitViewController” con inspectores para una visualización detallada del contenido y un ajuste dinámico del tamaño de las columnas.
- 3:21 - La barra de menú
iOS 26 mejora la barra de menús del iPad, a la que ahora se puede acceder deslizando el dedo desde la parte superior de la pantalla, para brindar un acceso rápido a las funciones de la app sin un teclado físico. La barra de menús siempre debe mostrar todos los comandos de la app, incluso aquellos que están deshabilitados o no tienen atajos de teclado. Personaliza la barra de menús con la nueva API para la configuración del menú principal e implementa menús dinámicos basados en la vista enfocada. Se incorporan acciones estándares como “Cerrar” y “Nuevo a partir del Portapapeles”. Las acciones para alinear el texto y mostrar u ocultar la barra lateral y el inspector ahora también se muestran para su personalización. Asegúrate de que las acciones estén disponibles en tu app sin depender de la barra de menús.
- 9:58 - Mejoras arquitectónicas
UIKit sigue evolucionando con nuevas funciones para patrones modernos, prácticas recomendadas y una mayor interoperabilidad con SwiftUI.
- 10:21 - Seguimiento automático de observaciones
UIKit ahora hace un seguimiento automático de los objetos Observable a los que se hace referencia en métodos de actualización como “layoutSubviews”, lo que elimina la necesidad de llamar manualmente a “setNeedsLayout”. Esta función está habilitada de forma predeterminada en iOS 26 y puede implementarse en iOS 18 con la clave “UIObservationTrackingEnabled” del archivo Info.plist. Los cambios en las propiedades del modelo Observable que actualizan elementos de la interfaz de usuario activan automáticamente la invalidación de la vista y la reejecución de los métodos de actualización relevantes, lo que mantiene la interfaz sincronizada sin código adicional.
- 12:33 - Nuevo método de actualización de la IU
UIKit introduce un nuevo método, “updateProperties”, disponible en “UIView” y “UIViewController”. Este método se ejecuta de forma independiente antes de “layoutSubviews” y te permite completar contenido, aplicar estilos y configurar comportamientos de manera más eficiente. “updateProperties” hace un seguimiento automático de los objetos Observable y, en caso contrario, se puede activar manualmente llamando a “setNeedsUpdateProperties”. Este método permite evitar pasos de diseño innecesarios, lo que mejora el rendimiento de tu app.
- 15:45 - Mejoras en las animaciones
En iOS 26, UIKit introduce “flushUpdates”, una opción de animación que aplica automáticamente las actualizaciones pendientes antes y después de las animaciones, lo que elimina la necesidad de llamar manualmente a “layoutIfNeeded”. Esto simplifica el código, reduce los errores y funciona con objetos Observable y cambios automáticos en las restricciones de diseño.
- 17:45 - Actualizaciones de escenas
Ahora puedes integrar escenas de SwiftUI en apps de UIKit con el nuevo protocolo “UIHostingSceneDelegate”. Crea apps que se adapten a diferentes dispositivos (como una app de meditación con un jardín zen 2D en iPhone y iPad y una experiencia inmersiva en visionOS) solicitando programáticamente una escena de SwiftUI específica.
- 18:55 - Compatibilidad con colores HDR
En iOS 26, UIKit también mejora el renderizado HDR más allá de las imágenes para incluir colores. Crea colores HDR con “UIColor” y permite seleccionarlos en los selectores de color. Utiliza la nueva función “UITraitHDRHeadroomUsage” para identificar cuándo corresponde una transición de HDR a SDR.
- 20:38 - Notificaciones Swift
En iOS 26, UIKit representa cada notificación como un tipo “NotificationCenter.Message” exclusivo, lo que proporciona notificaciones estrictamente tipificadas para facilitar el manejo de eventos, tal como se muestra en un ejemplo de ajuste del diseño cuando aparece el teclado.
- 21:20 - Migrar a un ciclo de vida basado en escenas
“UIScene” reemplaza “UIApplication” como estándar para el desarrollo de apps, lo que hace que las apps sean más portátiles y flexibles. Debes adoptar el ciclo de vida “UIScene” porque los métodos heredados están obsoletos. Además, a partir de la versión posterior a iOS 26, las apps que no hayan adoptado el ciclo de vida de escena no se iniciarán.
- 22:40 - Compatibilidad de OpenURL con URL de archivos
El método “openURL” ahora permite que las apps transfieran documentos no nativos a visores predeterminados o utilicen controladores de vista previa rápida si no existe un visor predeterminado.
- 23:17 - SF Symbols 7
SF Symbols 7 presenta nuevas capacidades de dibujo, incluidos los efectos “Draw Off” y “Draw On”, el modo de dibujo variable para representar valores arbitrarios a lo largo de una ruta y animaciones de dibujo especiales con transiciones de reemplazo mágico. UIKit ahora ofrece una API para facilitar la adopción de estas transiciones en “UIButton”, y los símbolos se pueden colorear con rellenos en degradé generados automáticamente.
- 25:13 - Próximos pasos
Para actualizar tu app para iOS 26, compílala con el nuevo SDK, ajusta los elementos de interfaz de usuario al nuevo diseño, utiliza contenedores estándares y las nuevas API de menú, y adopta el método “updateProperties” junto con el seguimiento de observaciones para mejorar el rendimiento.