Aunque mostrar un teclado numérico es un buen primer paso, en realidad no evita que se ingresen datos incorrectos:
- El usuario puede pegar texto no numérico en el campo de texto.
- Los usuarios de iPad seguirán teniendo un teclado completo
- Cualquier persona con un teclado Bluetooth conectado puede escribir cualquier cosa
Lo que realmente quieres hacer es desinfectar la entrada, así:
import SwiftUI
import Combine
struct StackOverflowTests: View {
@State private var numOfPeople = "0"
var body: some View {
TextField("Total number of people", text: $numOfPeople)
.keyboardType(.numberPad)
.onReceive(Just(numOfPeople)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
self.numOfPeople = filtered
}
}
}
}
Cada vez que numOfPeople
cambia, los valores no numéricos se filtran y el valor filtrado se compara para ver si numOfPeople
debe actualizarse por segunda vez, sobrescribiendo la entrada incorrecta con la entrada filtrada.
Tenga en cuenta que el Just
editor requiere que usted import Combine
.
EDITAR:
Para explicar al Just
editor, considere el siguiente esquema conceptual de lo que ocurre cuando cambia el valor en TextField
:
- Debido a que
TextField
toma a Binding
a a String
, cuando se cambia el contenido del campo, también escribe ese cambio nuevamente en la @State
variable.
- Cuando una variable marcada
@State
cambia, SwiftUI vuelve a calcular la body
propiedad de la vista.
- Durante el
body
cálculo, Just
se crea un editor. Combine tiene muchos editores diferentes para emitir valores a lo largo del tiempo, pero el Just
editor toma "solo" un solo valor (el nuevo valor de numberOfPeople
) y lo emite cuando se le solicita.
- El
onReceive
método convierte a View
un suscriptor en un editor, en este caso, el Just
editor que acabamos de crear. Una vez suscrito, solicita inmediatamente los valores disponibles del editor, de los cuales solo hay uno, el nuevo valor de numberOfPeople
.
- Cuando el
onReceive
suscriptor recibe un valor, ejecuta el cierre especificado. Nuestro cierre puede terminar de dos maneras. Si el texto ya es solo numérico, entonces no hace nada. Si el texto filtrado es diferente, se escribe en la @State
variable, que comienza el ciclo nuevamente, pero esta vez el cierre se ejecutará sin modificar ninguna propiedad.
Consulte Uso de Combinar para obtener más información.