简体   繁体   English

如何在 SwiftUI 中为 textField 制作“编辑”按钮?

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

I have some textFields that are already completed and I want to add some "Edit" buttons that will show the keyboard to the one that I press.我有一些已经完成的文本字段,我想添加一些“编辑”按钮,这些按钮将向我按下的那个显示键盘。 Here is the code to one of the textFields:这是文本字段之一的代码:

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)
}

This is what the textFields look like:这是 textFields 的样子: 在此处输入图片说明

It's very easy if you want to enable custom editMode to each different property.如果您想为每个不同的属性启用自定义 editMode,这非常容易。 Here I am creating custom editMode for only name field you just create editMode for other field like contact number you provided in above image.在这里,我只为姓名字段创建自定义编辑模式,您只需为其他字段创建编辑模式,例如您在上图中提供的联系号码。 First create an editMode property for every field like:首先为每个字段创建一个 editMode 属性,例如:

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

Then your each field should look like this:那么你的每个字段应该是这样的:

    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)
        }
    }

For testing just copy, paste and run the above code then see it's amazing.对于测试,只需复制、粘贴并运行上面的代码,然后就会发现它很棒。

This functionality is possible with a custom UIViewRepresentable .自定义UIViewRepresentable可以实现此功能。

This code is will create a custom TextField from a UITextField and allow you to change the parameters like font and autocapitalizationType you had.此代码将从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
        }
    }
}

Credit: This code is modified from an answer to a similar question by @MatteoPacini here .信用:此代码是从@MatteoPacini here对类似问题的回答中修改而来的。

I am assuming that PlainTextFieldStyle() is equivalent to UITextField.BorderStyle.none .我假设PlainTextFieldStyle()等效于UITextField.BorderStyle.none

So in your View , to have the "Edit" Button bring up the keyboard and change to "Done" to lower the keyboard, your code would be:因此,在您的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)
    }
}

With a Bool indicating if the TextField is editing:使用Bool指示TextField是否正在编辑:

@State var isEditing = false

If the code you provided defines the cell of a List or Form , you might replace this with an IndexSet or Optional<IndexPath> of the editing cell.如果您提供的代码定义了ListForm的单元格,您可以将其替换为编辑单元格的IndexSetOptional<IndexPath>

Also, if you do not want the "Done" Button, simply change the Button to:此外,如果您不想要“完成”按钮,只需将Button更改为:

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

Tested on a Swift Playground in Xcode-beta-2在 Xcode-beta-2 的 Swift Playground 上测试

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在按钮单击时在 SwiftUI 中为 TextField 设置文本 - How to set text for TextField in SwiftUI on button click 如何在 SwiftUI 中以编程方式编辑 TextField 的边框颜色? - How can I programmatically edit TextField's border color in SwiftUI? 如何修复 TextField 绑定<string>在 SwiftUI 中显示和编辑</string> - How to fix TextField Binding <String> to show and edit in SwiftUI 如何在SwiftUI中通过单击按钮(而不是通过使用NavigationLink)检查TextField的有效性? - How to check validation of TextField on Button Tap (not by using NavigationLink) in SwiftUI? 按下清除按钮时如何自动上一个文本字段 swiftui - How to automatically previous textfield when clear button press swiftui 我们如何使用“SwiftUI”添加“Button”和“TextField” - How can we add `Button` and `TextField` by using `SwiftUI` 使 TextField 将其内容包装在 SwiftUI - Make TextField wrap it content in SwiftUI 如何使 SwiftUi 文本字段更适合焦点 state? - How to make SwiftUi textfield more genric for focus state? 如何长按制作textField或UILabel,使其可以“复制”,但不能编辑 - How to make a textField or UILabel by long press,make it can be “copy”, but not to edit 在 SwiftUI 中显示和编辑文本的文本字段/视图是什么? - What textfield / view to show and edit text in SwiftUI?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM