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 numOfPeoplecambia, los valores no numéricos se filtran y el valor filtrado se compara para ver si numOfPeopledebe actualizarse por segunda vez, sobrescribiendo la entrada incorrecta con la entrada filtrada.
Tenga en cuenta que el Justeditor requiere que usted import Combine.
EDITAR:
Para explicar al Justeditor, considere el siguiente esquema conceptual de lo que ocurre cuando cambia el valor en TextField:
- Debido a que
TextFieldtoma a Bindinga a String, cuando se cambia el contenido del campo, también escribe ese cambio nuevamente en la @Statevariable.
- Cuando una variable marcada
@Statecambia, SwiftUI vuelve a calcular la bodypropiedad de la vista.
- Durante el
bodycálculo, Justse crea un editor. Combine tiene muchos editores diferentes para emitir valores a lo largo del tiempo, pero el Justeditor toma "solo" un solo valor (el nuevo valor de numberOfPeople) y lo emite cuando se le solicita.
- El
onReceivemétodo convierte a Viewun suscriptor en un editor, en este caso, el Justeditor 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
onReceivesuscriptor 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 @Statevariable, 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.