Dre*_*ohc 7 one-time-password uitextfield swiftui
我正在尝试为我的应用程序创建一个 OTP 页面,但在第一个文本字段中输入一个数字后,我不知道如何使下一个文本字段成为焦点。
我为 OTP 的每个数字创建了 6 个文本字段。一旦我从第一个文本字段中输入一个数字,下一个文本字段应该是第一个响应者,依此类推,直到所有 6 个数字都完成。
我不知道如何在 Swift UI 中做到这一点。到目前为止,我只成功创建了 6 行,如屏幕截图所示。预期每行只有一位数字。因此,一旦我输入单个整数,下一个文本字段应该成为焦点。
我尝试了其他帖子,例如使用@FocusState,但它说未知属性。
我还尝试了自定义文本字段How to move to next TextField in SwiftUI? 但我似乎无法让它发挥作用。
import SwiftUI
struct ContentView: View {
@State private var OTP1 = ""
@State private var OTP2 = ""
@State private var OTP3 = ""
@State private var OTP4 = ""
@State private var OTP5 = ""
@State private var OTP6 = ""
var body: some View {
VStack {
HStack(spacing: 16) {
VStack {
TextField("", text: $OTP1)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
VStack {
TextField("", text: $OTP2)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
VStack {
TextField("", text: $OTP3)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
VStack {
TextField("", text: $OTP4)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
VStack {
TextField("", text: $OTP5)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
VStack {
TextField("", text: $OTP6)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.frame(width: 41, height: 1)
}
}
}
}
}
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: 50))
}
}
Run Code Online (Sandbox Code Playgroud)
Alh*_*dhi 11
这是我对 iOS 14 的回答。
风景。
struct ContentView: View {
@StateObject var viewModel = ViewModel()
@State var isFocused = false
let textBoxWidth = UIScreen.main.bounds.width / 8
let textBoxHeight = UIScreen.main.bounds.width / 8
let spaceBetweenBoxes: CGFloat = 10
let paddingOfBox: CGFloat = 1
var textFieldOriginalWidth: CGFloat {
(textBoxWidth*6)+(spaceBetweenBoxes*3)+((paddingOfBox*2)*3)
}
var body: some View {
VStack {
ZStack {
HStack (spacing: spaceBetweenBoxes){
otpText(text: viewModel.otp1)
otpText(text: viewModel.otp2)
otpText(text: viewModel.otp3)
otpText(text: viewModel.otp4)
otpText(text: viewModel.otp5)
otpText(text: viewModel.otp6)
}
TextField("", text: $viewModel.otpField)
.frame(width: isFocused ? 0 : textFieldOriginalWidth, height: textBoxHeight)
.disabled(viewModel.isTextFieldDisabled)
.textContentType(.oneTimeCode)
.foregroundColor(.clear)
.accentColor(.clear)
.background(Color.clear)
.keyboardType(.numberPad)
}
}
}
private func otpText(text: String) -> some View {
return Text(text)
.font(.title)
.frame(width: textBoxWidth, height: textBoxHeight)
.background(VStack{
Spacer()
RoundedRectangle(cornerRadius: 1)
.frame(height: 0.5)
})
.padding(paddingOfBox)
}
}
Run Code Online (Sandbox Code Playgroud)
这是视图模型。
class ViewModel: ObservableObject {
@Published var otpField = "" {
didSet {
guard otpField.count <= 6,
otpField.last?.isNumber ?? true else {
otpField = oldValue
return
}
}
}
var otp1: String {
guard otpField.count >= 1 else {
return ""
}
return String(Array(otpField)[0])
}
var otp2: String {
guard otpField.count >= 2 else {
return ""
}
return String(Array(otpField)[1])
}
var otp3: String {
guard otpField.count >= 3 else {
return ""
}
return String(Array(otpField)[2])
}
var otp4: String {
guard otpField.count >= 4 else {
return ""
}
return String(Array(otpField)[3])
}
var otp5: String {
guard otpField.count >= 5 else {
return ""
}
return String(Array(otpField)[4])
}
var otp6: String {
guard otpField.count >= 6 else {
return ""
}
return String(Array(otpField)[5])
}
@Published var borderColor: Color = .black
@Published var isTextFieldDisabled = false
var successCompletionHandler: (()->())?
@Published var showResendText = false
}
Run Code Online (Sandbox Code Playgroud)
不是很可重用,但它可以工作......如果您想更改长度,请不要忘记更新 viewModelotpField
和didSet
views textFieldOriginalWidth
。
这里的想法是隐藏TextField
并让用户看起来像是在框中输入。
一个想法可能是通过TextField
使用. 您可能希望缩小它,以便用户无法粘贴文本或获取“弹出窗口”或文本字段光标。isEditing
TextField
归档时间: |
|
查看次数: |
8943 次 |
最近记录: |