尝试优化我的文本字段代码

问题描述 投票:0回答:1

我当前的代码可以工作,但我想看看是否有更好的方法。

我有一个视图设置,以便一旦用户开始在文本字段中输入数据,就会出现一个新的文本字段。

我想知道这是否可以通过 ForEach 循环来完成,或者是否有更好的方法来编写此代码。

这是模型

import FirebaseFirestore
import MetaCodable

@Codable
struct Trip: Identifiable, Equatable, Hashable {
    @DocumentID @Default(UUID().uuidString) var id: String?
    
    @Default("") var bol: String
    @Default("") var bol1: String
    @Default("") var bol2: String
    @Default("") var bol3: String
    @Default("") var bol4: String
    @Default("") var bol5: String
    @Default("") var bol6: String
    @Default("") var bol7: String
    @Default("") var bol8: String
    @Default("") var bol9: String
    
    init(
        bol: String = "",
        bol1: String = "",
        bol2: String = "",
        bol3: String = "",
        bol4: String = "",
        bol5: String = "",
        bol6: String = "",
        bol7: String = "",
        bol8: String = "",
        bol9: String = ""
    ) {
        self.bol = bol
        self.bol1 = bol1
        self.bol2 = bol2
        self.bol3 = bol3
        self.bol4 = bol4
        self.bol5 = bol5
        self.bol6 = bol6
        self.bol7 = bol7
        self.bol8 = bol8
        self.bol9 = bol9
    }
}

文本字段子视图

struct TextFieldRowView: View {
    let title: String
    let placeholder: String
    let width: CGFloat
    @Binding var text: String
    
    var body: some View {
        ViewThatFits(in: .horizontal) {
            LabeledContent {
                TextField(placeholder, text: $text)
                    .frame(width: width, alignment: .leading)
                    .textInputAutocapitalization(.words)
                    .autocorrectionDisabled()
            } label: {
                Text(title)
                    .bold()
            }
            
            VStack {
                Text(title)
                    .bold()
                
                TextField(placeholder, text: $text)
                    .frame(width: width, alignment: .leading)
                    .textInputAutocapitalization(.words)
                    .autocorrectionDisabled()
            }
        }
    }
}

和景色

import SwiftUI

struct AddEditTripView: View {
    
    @FocusState private var focusField: Field?
    
    @State private var bol = ""
    @State private var bol1 = ""
    @State private var bol2 = ""
    @State private var bol3 = ""
    @State private var bol4 = ""
    @State private var bol5 = ""
    @State private var bol6 = ""
    @State private var bol7 = ""
    @State private var bol8 = ""
    @State private var bol9 = ""
    
    var body: some View {
        Form {
            // MARK: - Trip Information
            Section {
                // MARK: - BOL
                TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol)
                    .focused($focusField, equals: .bol)
                    .submitLabel(.next)
                
                if !bol.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol1)
                        .focused($focusField, equals: .bol1)
                        .submitLabel(.next)
                }
                
                if !bol1.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol2)
                        .focused($focusField, equals: .bol2)
                        .submitLabel(.next)
                }
                
                if !bol2.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol3)
                        .focused($focusField, equals: .bol3)
                        .submitLabel(.next)
                }
                
                if !bol3.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol4)
                        .focused($focusField, equals: .bol4)
                        .submitLabel(.next)
                }
                
                if !bol4.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol5)
                        .focused($focusField, equals: .bol5)
                        .submitLabel(.next)
                }
                
                if !bol5.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol6)
                        .focused($focusField, equals: .bol6)
                        .submitLabel(.next)
                }
                
                if !bol6.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol7)
                        .focused($focusField, equals: .bol7)
                        .submitLabel(.next)
                }
                
                if !bol7.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol8)
                        .focused($focusField, equals: .bol8)
                        .submitLabel(.next)
                }
                
                if !bol8.isEmpty {
                    TextFieldRowView(title: "BOL:", placeholder: "bol", width: UIScreen.main.bounds.width - 230, text: $bol9)
                        .focused($focusField, equals: .bol9)
                        .submitLabel(.next)
                }
            }
        }
    }
}

extension AddEditTripView {
    private enum Field {
        case bol, bol1, bol2, bol3, bol4, bol5, bol6, bol7, bol8, bol9
    }
    
    private func focusNextField() {
        switch focusField {
        case .bol:
            focusField = .bol1
        case .bol1:
            focusField = .bol2
        case .bol2:
            focusField = .bol3
        case .bol3:
            focusField = .bol4
        case .bol4:
            focusField = .bol5
        case .bol5:
            focusField = .bol6
        case .bol6:
            focusField = .bol7
        case .bol7:
            focusField = .bol8
        case .bol8:
            focusField = .bol9
        case .bol9:
            focusField = nil
        case .none:
            break
        }
    }
}
swift swiftui
1个回答
0
投票

将所有

bol
存储到一个数组中,并使用
ForEach
迭代该数组。

@FocusState private var focusField: Field?

@State private var bols = Array(repeating: "", count: 10)

var body: some View {
    Form {
        Section {
            ForEach(0..<10) { i in
                if i == 0 || !bols[i - 1].isEmpty {
                    TextFieldRowView(
                        title: "BOL:",
                        placeholder: "bol",
                        width: UIScreen.main.bounds.width - 230,
                        text: $bols[i]
                    )
                    .focused($focusField, equals: Field(rawValue: i))
                    .submitLabel(.next)
                }
            }
        }
    }
}

注意

i == 0
析取。这无条件地显示第一个文本字段,并且仅当前一个字段不为空时才显示所有其他文本字段。

注意

Field(rawValue: i)
Field
应将
Int
作为其原始值类型。这使得使用
Field
轻松创建
Int
的值。您还可以轻松编写一个
nextField
方法:

enum Field: Int {
    case bol, bol1, bol2, bol3, bol4, bol5, bol6, bol7, bol8, bol9
    
    func nextField() -> Field? {
        Field(rawValue: rawValue + 1)
    }
}

然后移动到下一个字段就像这样简单,

.onSubmit {
    focusField = focusField?.nextField()
}
© www.soinside.com 2019 - 2024. All rights reserved.