Apple introdujo los widgets en iOS 14 y aportó una nueva apariencia que cambió las pantallas de inicio de nuestros teléfonos. El marco evolucionó a lo largo de los años, agregando un medio poderoso para mantener a los usuarios actualizados con sus datos. iOS 17 lleva los widgets al siguiente nivel al introducir la interactividad. Los usuarios ahora pueden interactuar con su aplicación de una manera nueva e innovadora que antes no era posible. Al hacer que las acciones esenciales de su aplicación estén disponibles en un widget, sus usuarios tienen una forma más conveniente y atractiva de interactuar con su aplicación. En este tutorial, agregará widgets interactivos a la aplicación Trask usando SwiftUI. Si está pensando en aprender SwiftUI, las vistas simples de los widgets son un excelente lugar para comenzar. Este tutorial cubre los siguientes temas. Qué son los widgets interactivos y cómo funcionan. Cómo crear widgets interactivos con una animación SwiftUI. Diferentes tipos de widgets interactivos que puedes crear. Mejores prácticas para diseñar y desarrollar widgets interactivos. Aunque no existen requisitos previos estrictos, un conocimiento básico de SwiftUI y WidgetKit puede resultar útil. De todos modos, no te preocupes, tendrás un resumen rápido para empezar con el pie derecho. Primeros pasos Descargue el proyecto inicial haciendo clic en el botón Descargar materiales en la parte superior o inferior de este tutorial. Abra el proyecto inicial (Trask.xcodeproj) en la carpeta Inicio. Cree y ejecute el proyecto, y debería ver la pantalla inicial de Trask. Trask es una aplicación de seguimiento general que rastrea diferentes tareas/cosas/hábitos durante el día, como la cantidad de vasos de agua, medicinas, yoga, etc. La primera vez que inicias la aplicación, Trask crea algunos datos de muestra para que puedas Puedes ver los diferentes tipos de tareas que puedes crear. Tarea con múltiples pasos. Tarea “TODO” con un solo paso. Al tocar el botón más, la aplicación avanza en la tarea y, una vez que alcanza su objetivo, pasa al estado completado. El usuario puede eliminar tareas deslizándolas hacia la izquierda y puede agregar otras nuevas usando el botón en la parte inferior de la Vista. . Recapitulando WidgetKit Antes de entrar en el tema candente de este tutorial, familiarícese con algunos conceptos básicos de WidgetKit para crear una terminología común para el resto del tutorial. Nota: Para aprender cómo agregar widgets y profundizar en los widgets, consulte el increíble tutorial Cómo comenzar con los widgets. Agregar un widget de iOS Trask viene con un widget estático para seguir el estado de una tarea seleccionable. Agregue una instancia del widget para ver cómo se ve. Construya y ejecute el proyecto. Minimiza la aplicación. Mantenga presionada una zona vacía de la pantalla. Luego toque el botón +, busque Trask y seleccione el widget disponible. Ahora está listo para saltar a la estructura del código para ver cómo funciona. Estructura del código del widget La carpeta TraskWidgets del proyecto inicial contiene todos los archivos relacionados con el widget. Hacer que el widget sea interactivo Compartir datos con el proveedor de la línea de tiempo de la aplicación Actualizar widgets Tipos de interactividad Widgets e intenciones Agregar la intención Como puede ver, el código del widget está contenido en un destino Xcode separado y iOS ejecuta el widget en un proceso diferente al de la aplicación. . Este detalle puede parecer sutil, pero es crucial si se considera que la aplicación y el widget deben compartir los mismos datos. El código del widget no puede simplemente llamar a algunas funciones en el destino de la aplicación. Entre las diferentes posibilidades, Trask utiliza una tienda UserDefault en un contenedor de App Group compartido entre la aplicación y el widget. La línea de tiempo es un concepto clave de los widgets. Para conservar la batería y los recursos del sistema, iOS no ejecuta constantemente su widget. En cambio, le pide a su proveedor de línea de tiempo que genere una serie de entradas de línea de tiempo para representar su widget y presentarlo en el momento adecuado. Su TaskTimelineProvider define tres métodos. Como se dijo anteriormente, la línea de tiempo (para: en:) devuelve la matriz de entradas en el momento especificado, pero ¿qué sucede después de que se presenta la última vista del widget? ¡Ingrese a la estrategia de actualización de widgets! Al devolver la línea de tiempo de las entradas, también proporciona una estrategia para actualizar la línea de tiempo. Puede elegir entre las tres opciones siguientes. En nuestro caso, el proveedor de la línea de tiempo de Trask devuelve las políticas .never ya que no es necesario que el widget actualice su vista. La única forma de actualizar el estado de una tarea es a través de la aplicación cuando el usuario toca para pasar a una tarea… hasta el siguiente capítulo. :]Vaya… fue un calentamiento largo, pero ahora está listo para agregar interacción al widget de estado de Trask. A partir de iOS 17, iPadOS 17 y macOS 14, Apple permite dos formas principales de interactividad con su widget: botones y botones. Como primera mejora, agregará un botón de paso al widget de estado de Trask para que los usuarios puedan avanzar en sus tareas favoritas sin abrir la aplicación. Al agregar interactividad, el botón del widget no puede invocar código en su aplicación, pero tiene que depender de una API pública expuesta por su aplicación: App Intents. Los intents de la aplicación exponen acciones de su aplicación al sistema para que iOS pueda realizarlas cuando sea necesario. Por ejemplo, cuando el usuario interactúa con el botón del widget. Además, también puedes utilizar la misma intención de aplicación para Siri y Atajos. En primer lugar, agregue el método de intención que su botón invocará cuando se presione. Abra TaskIntent.swift y agregue el método perform() a TaskIntent. El método perform() de AppIntent es el que se llama cuando se invoca un Intent. Este método toma la tarea seleccionada como entrada y llama a un método en la tienda para avanzar en esta tarea. Tenga en cuenta que UserDefaultStore es parte tanto de la aplicación como de la extensión del widget, por lo que puede reutilizar el mismo código en ambos destinos. :]A continuación, abra TaskStore.swift y agregue una definición del método stepTask(_:) al protocolo TaskStore. Luego, agregue el método stepTask(_:) a UserDefaultStore. Este método carga todas las tareas contenidas en la tienda, encuentra la tarea requerida, llama al método de progreso () de la tarea y la guarda nuevamente en la tienda. Finalmente, agregue un método stepTask(_:) vacío a SampleStore para que cumpla con la nueva definición de protocolo. TaskIntent es una intención que se ajusta al protocolo WidgetConfigurationIntent. Aquí, la intención permite la selección de tareas en el menú Editar widget. TaskStatusWidget es el widget real. Cuatro partes componen el archivo del widget. TaskTimelineProvider especifica cuándo iOS debe actualizar la pantalla del widget. TaskEntry representa el modelo de la vista del widget. Contiene una fecha que iOS usa para actualizar la vista del widget con el elemento de tarea. TaskStatusWidgetEntryView define la vista del widget usando SwiftUI. Contiene una entrada de línea de tiempo como parámetro y debe diseñar el widget según el valor de este parámetro. TaskStatusWidget une todas las partes dentro de una WidgetConfiguration. Finalmente, TraskWidgetBundle declara todos los widgets de la extensión. placeholder(in:) debería devolver algunos datos de muestra para representar la interfaz de usuario del marcador de posición mientras se espera que el widget esté listo. SwiftUI aplica un efecto de redacción a esta vista. snapshot(for:in:) proporciona los datos para representar el widget en la galería presentada al elegir un widget. timeline(for:in:) es el método principal que devuelve las entradas de la línea de tiempo para presentarlas en el momento especificado. .atEnd vuelve a calcular la línea de tiempo después de que pase la última fecha en la línea de tiempo. .after(_:) especifica aproximadamente cuándo solicitar una nueva línea de tiempo. .never le dice al sistema que nunca vuelva a calcular la línea de tiempo. La aplicación avisará a WidgetKit cuando haya una nueva línea de tiempo disponible. Los botones son adecuados para representar una acción sobre el contenido del widget. Activa o desactiva la identificación de un estado binario procesable. Como el estado de nuestra tarea TODO. Nota: En un dispositivo bloqueado, los botones y los conmutadores están inactivos y iOS no realiza acciones hasta que el usuario desbloquea su dispositivo. func perform() lanzamientos asíncronos -> algunos IntentResult { UserDefaultStore().stepTask(taskEntity.task) return .result() } protocolo TaskStore { func loadTasks() -> [TaskItem]func saveTasks(_ tareas: [TaskItem]) func stepTask(_ tarea: TaskItem) } func stepTask(_ tarea: TaskItem) { var tareas = loadTasks() guard let index = tareas.firstIndex(donde: { $0.id == tarea.id }) else { return } tareas[index].progress() saveTasks(tasks) } TaskIntent es un intent que se ajusta al protocolo WidgetConfigurationIntent. Aquí, la intención permite la selección de tareas en el menú Editar widget. TaskStatusWidget es el widget real. Cuatro partes componen el archivo del widget. TaskTimelineProvider especifica cuándo iOS debe actualizar la pantalla del widget. TaskEntry representa el modelo de la vista del widget. Contiene una fecha que iOS usa para actualizar la vista del widget con el elemento de tarea. TaskStatusWidgetEntryView define la vista del widget usando SwiftUI. Contiene una entrada de línea de tiempo como parámetro y debe diseñar el widget según el valor de este parámetro. TaskStatusWidget une todas las partes dentro de una WidgetConfiguration. Finalmente, TraskWidgetBundle declara todos los widgets de la extensión. placeholder(in:) debería devolver algunos datos de muestra para representar la interfaz de usuario del marcador de posición mientras se espera que el widget esté listo. SwiftUI aplica un efecto de redacción a esta vista. snapshot(for:in:) proporciona los datos para representar el widget en la galería presentada al elegir un widget. timeline(for:in:) es el método principal que devuelve las entradas de la línea de tiempo para presentarlas en el momento especificado. .atEnd vuelve a calcular la línea de tiempo después de que pase la última fecha en la línea de tiempo. .after(_:) especifica aproximadamente cuándo solicitar una nueva línea de tiempo. .never le dice al sistema que nunca vuelva a calcular la línea de tiempo. La aplicación avisará a WidgetKit cuando haya una nueva línea de tiempo disponible. Los botones son adecuados para representar una acción sobre el contenido del widget. Activa o desactiva la identificación de un estado binario procesable. Como el estado de nuestra tarea TODO. Nota: En un dispositivo bloqueado, los botones y los conmutadores están inactivos y iOS no realiza acciones hasta que el usuario desbloquea su dispositivo. func perform() lanzamientos asíncronos -> algunos IntentResult { UserDefaultStore().stepTask(taskEntity.task) return .result() } protocolo TaskStore { func loadTasks() -> [TaskItem]func saveTasks(_ tareas: [TaskItem]) func stepTask(_ tarea: TaskItem) } func stepTask(_ tarea: TaskItem) { var tareas = loadTasks() guard let index = tareas.firstIndex(donde: { $0.id == tarea.id }) else { return } tareas[index].progress() saveTasks(tasks) } TaskTimelineProvider especifica cuándo iOS debe actualizar la pantalla del widget. TaskEntry representa el modelo de la vista del widget. Contiene una fecha que iOS usa para actualizar la vista del widget con el elemento de tarea. TaskStatusWidgetEntryView define la vista del widget usando SwiftUI. Contiene una entrada de línea de tiempo como parámetro y debe diseñar el widget según el valor de este parámetro. TaskStatusWidget une todas las partes dentro de una WidgetConfiguration. Finalmente, TraskWidgetBundle declara todos los widgets de la extensión. placeholder(in:) debería devolver algunos datos de muestra para representar la interfaz de usuario del marcador de posición mientras se espera que el widget esté listo. SwiftUI aplica un efecto de redacción a esta vista. snapshot(for:in:) proporciona los datos para representar el widget en la galería presentada al elegir un widget. timeline(for:in:) es el método principal que devuelve las entradas de la línea de tiempo para presentarlas en el momento especificado. .atEnd vuelve a calcular la línea de tiempo después de que pase la última fecha en la línea de tiempo. .after(_:) especifica aproximadamente cuándo solicitar una nueva línea de tiempo. .never le dice al sistema que nunca vuelva a calcular la línea de tiempo. La aplicación avisará a WidgetKit cuando haya una nueva línea de tiempo disponible. Los botones son adecuados para representar una acción sobre el contenido del widget. Activa o desactiva la identificación de un estado binario procesable. Como el estado de nuestra tarea TODO. Nota: En un dispositivo bloqueado, los botones y los conmutadores están inactivos y iOS no realiza acciones hasta que el usuario desbloquea su dispositivo. func perform() lanzamientos asíncronos -> algunos IntentResult { UserDefaultStore().stepTask(taskEntity.task) return .result() } protocolo TaskStore { func loadTasks() -> [TaskItem]func saveTasks(_ tareas: [TaskItem]) func stepTask(_ tarea: TaskItem) } func stepTask(_ tarea: TaskItem) { var tareas = loadTasks() guard let index = tareas.firstIndex(donde: { $0.id == tarea.id }) else { return } tareas[index].progress() saveTasks(tareas) } func stepTask(_ tarea: TaskItem) {}

Source link