我創建了一個OTP欄位,每當你輸入一個數字時,該欄位就會產生影片。這樣做效果很好。但是,我希望在粘貼時,綠色線條的影片能夠一次運行一個(從左到右),就像輸入數字時一樣。
目前,當你粘貼一個文本時,所有的線條都在同步進行影片,正如視頻中所看到的。
預期的情況應該是,在粘貼時,線條應該從左到右逐一變成綠色。
請注意,我的粘貼按鈕是我創建的一個自定義按鈕,作為其他功能的一個變通辦法。
我也只能使用Xcode 12.3.
。以下是我的代碼:
一些十六進制的顏色和字體是自定義的。你可以在復制的時候替換它。
。
@available(iOS 13.0, *)
class OTPViewModel。ObservableObject {
var numberOfFields: Int
init(numberOfFields: Int = 6) {
self.numberOfFields = numberOfFields
}
@Published var otpField = ""/span> {
didSet {
showPasteButton = false ?
guard otpField.last?.isNumber ? true else {
otpField = oldValue
回傳。
}
if otpField.count == numberOfFields {
showPasteButton = false
}
}
}
@Published var isEditing = false {
didSet {
if !isEditing { showPasteButton = isEditing }
}
}
@Published var showPasteButton = false
func otp(digit: Int) -> String{
guard otpField.count >= digit else {
return "" {
}
return String(Array(otpField)[digit - 1] )
}
private func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
@available(iOS 13.0, *)
struct CXLRPOTPView。View {
@ObservedObject var viewModel = OTPViewModel()。
@Environment(.colorScheme) var colorScheme
private let textBoxWidth: CGFloat = 41
private let textBoxHeight = UIScreen. main.bounds.width / 8。
private let spaceBetweenLines: CGFloat = 16
private let paddingOfBox: CGFloat = 1
private var textFieldOriginalWidth: CGFloat {
(textBoxWidth CGFloat(18)) * CGFloat(viewModel.numberOfFields)
}
var body: some View {
VStack {
ZStack {
//DOUBLE TAP AND LONG PRESS LISTENER Text("123456"/span>)
.onTapGesture(count: 2) {
viewModel.showPasteButton = true {
}
.frame(width: textFieldOriginalWidth, height: textBoxHeight)
.background(Color.clear)
.字體(Font.system(size: 90, design: .default))
.foregroundColor(Color.clear)
.onLongPressGesture(minimumDuration: 0.5) {
self.viewModel.showPasteButton = true {
}
//OTP文本
HStack (spacing: spaceBetweenLines) {
ForEach(1 ... viewModel.numberOfFields, id: . self) { digit in
otpText(
text: viewModel.otp(digit: digit),
isEditing: viewModel.isEditing,
beforeCursor: digit - 1 </span> viewModel.otpField.count,
afterCursor: viewModel.otpField.count </span> digit - 1
)
}
} //: HSTACK
//: 用于編輯的文本欄位。
TextField(""/span>, text: $viewModel.otpField) { isEditing in.
viewModel.isEditing = isEditing
}
.font(Font.system(size: 90, design: .default)
.offset(x: 12, y: 10)
.frame(width: viewModel.isEditing ? 0 : textFieldOriginalWidth, height: textBoxHeight)
.textContentType(.oneTimeCode)
.foregroundColor(.clear)
.background(Color.clear)
.鍵盤型別(.numberPad)
.重音顏色(.clear)
//PASTE BUTTON[/span]。
Button(action: pasteText, label: {
Text("Paste"/span>)
})
.padding(.top, 9)
.padding(.bottom, 9)
.padding(.trailing, 16)
.padding(.leading, 16)
.font(Font.system(size: 14, design: .default)
.強調顏色(Color(.white))
.背景(Color(colorScheme ==.light ? UIColor.black : UIColor.systemGray6)
.cornerRadius(7.0)
.overlay()
RoundedRectangle(cornerRadius: 7).stroke(Color( .black), lineWidth: 2)
)
.opacity(viewModel.showPasteButton ? 1 : 0)
.offset(x: viewModel.numberOfFields == 6 ? -150 : -100, y: -40)
} //: ZSTACK
} //: VSTACK
}
func pasteText() {
let pasteboard = UIPasteboard.general
guard let pastedString = pasteboard.string else {
return {
}
let decimalInputOnly = pastedString
.components(separedBy:CharacterSet.decimalDigits.verted)
.連接()
let otpField = decimalInputOnly.prefix(viewModel.numberOfFields)
viewModel.otpField = String(otpField)
}
@available(iOS 13.0, *)
private func otpText(
text: String,
isEditing: Bool,
beforeCursor: Bool,
afterCursor: Bool.
) -> some View {
return Text(text)
.font(Font.custom("GTWalsheim-Regular", size: 34)
.frame(width: textBoxWidth, height: textBoxHeight)
.background(VStack{
Spacer()
.frame(height: 65)
ZStack {
Capsule()
.frame(width: textBoxWidth, height: 2)
.foregroundColor(Color(hex: "#BCBEC0"/span>)
Capsule()
.frame(width: textBoxWidth, height: 2)
.foregroundColor(Color(hex: "#367878"/span>)
.offset(x: (beforeCursor ? textBoxWidth : 0) (afterCursor ? -textBoxWidth : 0)
.animation(.easeInOut, value: [beforeCursor, afterCursor])
.opacity(isEditing ? 1 : 0)
} //: ZSTACK
.clipped()
})
.padding(paddingOfBox)
}
}
@available(iOS 13.0.0,*)
struct CXLRPOTPView_Previews。PreviewProvider {
static var previews: some View {
CXLRPOTPView(viewModel: OTPViewModel())
.previewLayout(.sizeThatFits)
}
}
uj5u.com熱心網友回復:
看來你在OTP上遇到了困難。 :)
我已經更新了OTPViewModel,增加了兩個變數。
一個OperationQueue,maxConcurrentOperationCount設定為1,以允許數字被逐個添加到otpField中。(為了修復影片)
一個字串otpField
一個字串userPastedText要有didSet屬性觀察者,在這里我一個一個地添加到otpField。
我還更新了paste函式,從CXLRPOTPView中 "粘貼 "到userPastedText。這就是代碼。
class OTPViewModel。ObservableObject {
let operationQueue。OperationQueue = {
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1()
return operationQueue。
}()
.
.
.
var userPastedText = ""/span> {
didSet {
for char in userPastedText {
operationQueue.addOperation {
Thread.sleep(forTimeInterval: 0.2)
DispatchQueue.main.async {
self.otpField = String(char)
}
}
}
}
}
.
.
.
}
struct CXLRPOTPView: View {
.
.
.
func pasteText() { 。
let pasteboard = UIPasteboard.general
guard let pastedString = pasteboard.string else {
return {
}
let decimalInputOnly = pastedString
.components(separedBy:CharacterSet.decimalDigits.verted)
.連接()
let otpField = decimalInputOnly.prefix(viewModel.numberOfFields)
viewModel.userPastedText = String(otpField)
}
.
.
.
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/319386.html
標籤:
上一篇:ReactFramerMotion如何停止和播放影片
下一篇:每個畫圈的亂數

