You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:45:03