簡體   English   中英

如何在 SwiftUI 中為 textField 制作“編輯”按鈕?

[英]How to make an "Edit" button for a textField in SwiftUI?

我有一些已經完成的文本字段,我想添加一些“編輯”按鈕,這些按鈕將向我按下的那個顯示鍵盤。 這是文本字段之一的代碼:

Image(colorScheme == .light ? "user" : "userDark").resizable().frame(width: 30, height: 30)
TextField("Name", text: $name).textFieldStyle(PlainTextFieldStyle()).padding(.leading, 5).font(.system(size: 20))
    .autocapitalization(.words)
    .disableAutocorrection(true)
if name != localName {
    Button(action: {
            self.name = ""
    }) {
        Text("Update").font(.system(size: 15)).fontWeight(.light)
            .foregroundColor(colorScheme == .light ? Color.black : Color.white)
    }
} else if name == localName {
    Text("Edit").font(.system(size: 15)).fontWeight(.light)
        .foregroundColor(colorScheme == .light ? Color.black : Color.white)
}

這是 textFields 的樣子: 在此處輸入圖片說明

如果您想為每個不同的屬性啟用自定義 editMode,這非常容易。 在這里,我只為姓名字段創建自定義編輯模式,您只需為其他字段創建編輯模式,例如您在上圖中提供的聯系號碼。 首先為每個字段創建一個 editMode 屬性,例如:

@State var nameInEditMode = false
@State var name = "Mr. Foo Bar"

那么你的每個字段應該是這樣的:

    HStack {
        Image(systemName: "person.circle").resizable().frame(width: 30, height: 30)

        if nameInEditMode {
            TextField("Name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle()).padding(.leading, 5).font(.system(size: 20))
            .autocapitalization(.words)
            .disableAutocorrection(true)
        } else {
            Text(name).font(.system(size: 20))
        }

        Button(action: {
            self.nameInEditMode.toggle()
        }) {
            Text(nameInEditMode ? "Done" : "Edit").font(.system(size: 20)).fontWeight(.light)
                .foregroundColor(Color.blue)
        }
    }

對於測試,只需復制、粘貼並運行上面的代碼,然后就會發現它很棒。

自定義UIViewRepresentable可以實現此功能。

此代碼將從UITextField創建自定義TextField並允許您更改fontautocapitalizationType等參數。

struct CustomTextField: UIViewRepresentable {

    class Coordinator: NSObject, UITextFieldDelegate {

        @Binding var text: String
        @Binding var isEditing: Bool
        var didBecomeFirstResponder = false

        init(text: Binding<String>, editing: Binding<Bool>) {
            _text = text
            _isEditing = editing
        }

        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }

        func textFieldDidBeginEditing(_ textField: UITextField) {
            isEditing = true
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            isEditing = false
        }

    }

    var placeholder = ""
    @Binding var text: String
    @Binding var isEditing: Bool
    var isFirstResponder: Bool = false
    var font = UIFont.systemFont(ofSize: 20)
    var autocapitalization = UITextAutocapitalizationType.none
    var autocorrection = UITextAutocorrectionType.default
    var borderStyle = UITextField.BorderStyle.none

    func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        textField.placeholder = placeholder
        textField.font = font
        textField.autocapitalizationType = autocapitalization
        textField.autocorrectionType = autocorrection
        textField.borderStyle = borderStyle
        return textField
    }

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

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

信用:此代碼是從@MatteoPacini here對類似問題的回答中修改而來的。

我假設PlainTextFieldStyle()等效於UITextField.BorderStyle.none

因此,在您的View ,要讓“編輯” Button出鍵盤並更改為“完成”以降低鍵盤,您的代碼將是:

Image(colorScheme == .light ? "user" : "userDark")
    .resizable()
    .frame(width: 30, height: 30)
CustomTextField(
    placeholder: "Name",
    text: $name,
    isEditing: $isEditing,
    isFirstResponder: isEditing,
    font: .systemFont(ofSize: 20),
    autocapitalization: .words,
    autocorrection: .no,
    borderStyle: .none
)
    .padding(.leading, 5)
if name != localName {
    Button(action: {
        self.name = ""
    }) {
        Text("Update")
            .font(.system(size: 15))
            .fontWeight(.light)
            .foregroundColor(colorScheme == .light ? Color.black : Color.white)
    }
} else if name == localName {
    Button(action: {
        self.isEditing.toggle()
    }) {
        Text(self.isEditing ? "Cancel" : "Edit")
            .font(.system(size: 15))
            .fontWeight(.light)
            .foregroundColor(colorScheme == .light ? Color.black : Color.white)
    }
}

使用Bool指示TextField是否正在編輯:

@State var isEditing = false

如果您提供的代碼定義了ListForm的單元格,您可以將其替換為編輯單元格的IndexSetOptional<IndexPath>

此外,如果您不想要“完成”按鈕,只需將Button更改為:

Button(action: {
    self.isEditing = true
}) {
    Text("Edit")
        .font(.system(size: 15))
        .fontWeight(.light)
        .foregroundColor(colorScheme == .light ? Color.black : Color.white)
}

在 Xcode-beta-2 的 Swift Playground 上測試

https://stackoverflow.com/a/56508132/13231930

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM