基于SwiftUI TextField实现OTP验证码页 输入单字符自动跳转下一个输入框
OTP验证码输入框实现方案
以下代码可直接运行,实现了输入单字自动跳转、单字符限制、删除回退的效果,兼容你现有的底部横线布局:
import SwiftUI enum OTPField: Int, CaseIterable { case field1, field2, field3, field4, field5, field6 } struct ContentView: View { @State private var otpValues = Array(repeating: "", count: 6) @FocusState private var focusedField: OTPField? var body: some View { VStack { HStack(spacing: 16) { ForEach(OTPField.allCases, id: \.rawValue) { field in VStack { TextField("", text: Binding( get: { otpValues[field.rawValue] }, set: { newValue in // 过滤非数字,限制长度1 let filtered = newValue.filter { $0.isNumber } otpValues[field.rawValue] = String(filtered.prefix(1)) // 输入满1位跳下个,清空跳上个 if !filtered.isEmpty { focusedField = OTPField(rawValue: field.rawValue + 1) } else if field.rawValue > 0 { focusedField = OTPField(rawValue: field.rawValue - 1) } } )) .focused($focusedField, equals: field) .keyboardType(.numberPad) .multilineTextAlignment(.center) .font(.title) .frame(width: 41) Line() .stroke(style: StrokeStyle(lineWidth: 1)) .frame(width: 41, height: 1) } } } } .onAppear { // 进入页面自动聚焦第一个输入框 focusedField = .field1 } } } struct Line: Shape { func path(in rect: CGRect) -> Path { var path = Path() path.move(to: CGPoint(x: 0, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: 0)) return path } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .previewLayout(.fixed(width: 560, height: 100)) } }
注意事项
@FocusState是iOS 15+才支持的属性,如果提示未知属性,说明你的项目兼容版本低于iOS15,需要用UIViewRepresentable封装UITextField,调用becomeFirstResponder实现焦点控制- 代码里用数组存储OTP值比单独声明6个变量更简洁,最后需要提交验证码的时候直接拼接
otpValues.joined()就能拿到完整的6位验证码
内容的提问来源于stack exchange,提问作者Dreiohc
相关产品推荐
相关产品推荐

