SwiftUI 中的短信验证码设计和功能

问题描述

我尝试用六个文本字段来实现它,但发现了很多问题,因为做了很多工作,除了第一个文本字段之外的所有初始输入都被阻塞,firstResponder 的延迟移动等等,是什么让我想知道是否有 6 个文本字段真的是最好的方法。

难点在于功能(即光标平滑移动、前后移动、输入错误时将所有光标变为红色等)我如何实现这样的行为/功能?

截图:-

Design

代码如下:-

import SwiftUI

struct VerficationCode: View {
@State private var numberOfCells: Int = 6
@State private var currentlySelectedCell = 0

var body: some View {
HStack {
    Group {
        ForEach(0 ..< self.numberOfCells) { index in
            CharacterInputCell(currentlySelectedCell: self.$currentlySelectedCell,index: index)
        }
    }.frame(width:15,height: 56)
    .padding(.horizontal)
    .foregroundColor(.white)
    .cornerRadius(10)
    .keyboardType(.numberPad)
     }
   }
 }

struct CharacterInputCell: View {
@State private var textValue: String = ""
@Binding var currentlySelectedCell: Int

var index: Int

var responder: Bool {
return index == currentlySelectedCell
}

 var body: some View {
 CustomTextField(text: $textValue,currentlySelectedCell: $currentlySelectedCell,isFirstResponder: responder)
  }
 }

 struct CustomTextField: UIViewRepresentable {

class Coordinator: NSObject,UITextFieldDelegate {

@Binding var text: String
@Binding var currentlySelectedCell: Int

var didBecomeFirstResponder = false

init(text: Binding<String>,currentlySelectedCell: Binding<Int>) {
    _text = text
    _currentlySelectedCell = currentlySelectedCell
}

func textFieldDidChangeSelection(_ textField: UITextField) {
    DispatchQueue.main.async {
        self.text = textField.text ?? ""
    }
}

func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool {
    let currentText = textField.text ?? ""
    guard let stringRange = Range(range,in: currentText) else { return false }
    let updatedText = currentText.replacingCharacters(in: stringRange,with: string)
    if updatedText.count <= 1 {
        self.currentlySelectedCell += 1
      }
       return updatedText.count <= 1
     }
    }

   @Binding var text: String
   @Binding var currentlySelectedCell: Int
   var isFirstResponder: Bool = false

 func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {
 let textField = UITextField(frame: .zero)
 textField.delegate = context.coordinator
 textField.textAlignment = .center
 textField.keyboardType = .decimalPad
 return textField
 }

 func makeCoordinator() -> CustomTextField.Coordinator {
return Coordinator(text: $text,currentlySelectedCell: $currentlySelectedCell)
 }

 func updateUIView(_ uiView: UITextField,context: UIViewRepresentableContext<CustomTextField>) {
uiView.text = text
if isFirstResponder && !context.coordinator.didBecomeFirstResponder  {
    uiView.becomeFirstResponder()
    context.coordinator.didBecomeFirstResponder = true
        }
      }
  }

有人可以向我解释我如何实现这样的行为/功能吗?我已经尝试实施但还没有结果。

任何帮助将不胜感激。

提前致谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)