Definir reglas para mostrar tips en TipKit
Misael Cuevas
26 octubre, 20236min de lectura
Si aún no sabes lo que es TipKit y quieres aprender a usarlo, te recomiendo este artículo en nuestro blog antes de continuar.
Puedes definir reglas para controlar cuándo se debe mostrar un tip. TipKit ofrece dos formas de hacerlo: basadas en Parámetros y en Eventos.
App de ejemplo en SwiftUI
A modo de demostración, crea un proyecto de iOS con SwiftUI en Xcode 15 y reemplaza el contenido del archivo ContentView.swift con el siguiente código:
import SwiftUIimport TipKit// 1struct CountTip: Tip {var title: Text {Text("Press the text to count")}var message: Text? {Text("The text will change when you tap it.")}var image: Image? {Image(systemName: "hand.tap.fill")}}// 2struct ContentView: View {@State var number = 0var countTip = CountTip()var body: some View {VStack {TipView(countTip)Text("\(number)").onTapGesture {number += 1}.font(.title)}.padding()}}#Preview {ContentView()}
Este código define:
- Un tip con título, mensaje e imagen.
- Una vista de SwiftUI con el tip
CountTip
y que cuenta el número de veces que se presiona el texto. Utiliza una variable de estadonumber
para almacenar la cantidad de veces que se presiona el texto y muestra el número en un formato de título.
Abre la estructura que conforma el protocolo App
, añade import TipKit
y el siguiente código después de la definición de la vista principal que se encuentra dentro del WindowGroup
:
.task {try? Tips.resetDatastore()try? Tips.configure()}
En este código, habilitas TipKit y reinicias todos los tips a su estado inicial para permitir mostrar los tips cada vez que ejecutes la app en el simulador o dispositivo.
Al ejecutar el proyecto, la app de ejemplo debe verse como se muestra a continuación:
Si quieres probar los tips desde el Canvas de Xcode agrega el código anterior dentro de la #Preview
de la ContentView
, ejemplo:
#Preview {ContentView().task {try? Tips.resetDatastore()try? Tips.configure()}}
Parámetros
Las reglas basadas en parámetros se relacionan con el estado de la app, lo que significa que su valor persiste a menos que utilices Tips.resetDatastore()
.
En la app de ejemplo, para añadir un parámetro que muestre el tip cuando se presiona el texto, ve la estructura CountTip
y añade el siguiente código después de la variable image
:
// 1@Parameterstatic var isTextTapped: Bool = false// 2var rules: [Rule] {[// 3#Rule(Self.$isTextTapped) {// 4$0 == true}]}
- La variable
isTextTapped
de tipoBool
con el macro@Parameter
. - La propiedad
rules
, que pertenece al protocoloTip
, contiene el arreglo de reglas que determinan cuándo se debe mostrar el tip. - Se añade el parámetro
isTextTapped
utilizando el macro#Rule
. - Se define la condición para cumplir con esta regla, que en este caso significa que el parámetro
isTextTapped
debe ser igual atrue
.
Ve a la vista ContentView
y añade el siguiente código dentro del modificador .onTapGesture
del Text
:
CountTip.isTextTapped.toggle()
Este código alterna el valor del parámetro isTextTapped
, cuando es true
se muestra el tip, de lo contrario no se muestra.
Al ejecutar el proyecto y presionar el Text
, la app de ejemplo debe mostrar/ocultar el tip:
Si deseas que el valor de isTextTapped
vuelva a su estado inicial (en este caso false
) la primera vez que se hace referencia a él, utiliza la opción .transient
en el macro @Parameter
, como se muestra a continuación:
@Parameter(.transient)
Eventos
Las reglas basadas en eventos se relacionan con las interacciones realizadas por el usuario. Por ejemplo, para mostrar el CountTip
cuando el usuario ha presionado el texto más de 5 veces, ve a la estructura CountTip
y añade lo siguiente después del parámetro isTextTapped
:
static let didTriggerTapTextEvent = Event(id: "didTriggerTapTextEvent")
Este código define el evento didTriggerTapTextEvent
con un identificador para registrar la cantidad de veces que el usuario ha presionado el texto.
Ahora reemplaza la variable rules
por este código:
// 1var rules: [Rule] {[// 2#Rule(Self.didTriggerTapTextEvent) {// 3$0.donations.count > 5}]}
- La propiedad
rules
, que pertenece al protocoloTip
, contiene un arreglo de reglas que determinan cuándo se debe mostrar el tip. - Se añade el evento
didTriggerTapTextEvent
utilizando el macro#Rule
. - Se define la condición para cumplir con esta regla, que en este caso significa que el evento
didTriggerTapTextEvent
debe haber ocurrido más de 5 veces. La propiedaddonations
registra la cantidad de veces que ha ocurrido un evento y otras informaciones relacionadas.
Ve a la vista ContentView
y añade el siguiente código dentro del modificador .onTapGesture
del Text
:
Task { await CountTip.didTriggerTapTextEvent.donate() }
Este código indica que cuando se presiona el texto, se registra el evento didTriggerTapTextEvent
de forma asíncrona.
Al ejecutar el proyecto y presionar el Text
más de 5 veces, la app de ejemplo debe mostrar el tip:
Puedes especificar que el evento ocurra dentro de un período de tiempo utilizando la función donatedWithin(_:)
. Por ejemplo:
#Rule(Self.didTriggerTapTextEvent) {$0.donations.donatedWithin(.week).count > 5}
Esta regla establece que el tip se mostrará cuando el evento didTriggerTapTextEvent
haya ocurrido más de 5 veces en la última semana. En lugar de .week
, puedes utilizar .minute
, .hour
, .day
o una variante con un valor específico.
También puedes ser más específico con los eventos, ya que admiten valores asociados, como un modelo de datos:
static let didTriggerTapTextEvent = Event<MyModel>(id: "didTriggerTapTextEvent")
Puedes utilizar este evento para crear una regla que solo muestre el tip cuando alguna propiedad de MyModel
cumpla con ciertos requisitos.
Combinar reglas
Como has visto, la propiedad rules
del protocolo Tip
puede contener un arreglo de reglas, por lo que puedes añadir tantos parámetros y eventos como desees y combinarlos. Al combinar reglas, todas estas deben cumplir con su condición para mostrar el tip.
var rules: [Rule] {[#Rule(Self.$isTextTapped) {$0 == true},#Rule(Self.didTriggerTapTextEvent) {$0.donations.count > 5}]}
En este ejemplo, ambas reglas deben cumplirse para mostrar el tip: el parámetro isTextTapped
debe ser true y el evento didTriggerTapTextEvent
debe haber ocurrido más de 5 veces.
En esta sección, utilizaste el macro
#Rule
. Si deseas obtener más información sobre los macros en Swift y cómo crear uno, te recomiendo este artículo en nuestro blog.