Extend SwiftUI Keyboard with Custom Button

前端 未结 3 1573
醉话见心
醉话见心 2020-12-28 18:32

I\'m trying to find a way to add a key or button to the SwiftUI numberPad. The only references I have found say it is not possible. In the Swift world I added a toolbar with

相关标签:
3条回答
  • 2020-12-28 18:56

    If there is an issue with @Binding implement the Coordinator class which conforms to the UITextFieldDelegate. This will allow one to be able to customize the TextField further if required.

    struct DecimalTextField: UIViewRepresentable {
         private var placeholder: String
         @Binding var text: String
    
         init(_ placeholder: String, text: Binding<String>) {
            self.placeholder = placeholder
            self._text = text
         } 
    
         func makeUIView(context: Context) -> UITextField {
            let textfield = UITextField()
            textfield.keyboardType = .decimalPad
            textfield.delegate = context.coordinator
            textfield.placeholder = placeholder
            let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: textfield.frame.size.width, height: 44))
            let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(textfield.doneButtonTapped(button:)))
            toolBar.items = [doneButton]
            toolBar.setItems([doneButton], animated: true)
            textfield.inputAccessoryView = toolBar
            return textfield
         }
    
         func updateUIView(_ uiView: UITextField, context: Context) {
            uiView.text = text
         }
    
         func makeCoordinator() -> Coordinator {
            Coordinator(self)
         }
    
         class Coordinator: NSObject, UITextFieldDelegate {
            var parent: DecimalTextField
        
         init(_ textField: DecimalTextField) {
            self.parent = textField
         }
        
         func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
             if let currentValue = textField.text as NSString? {
                 let proposedValue = currentValue.replacingCharacters(in: range, with: string) as String
                 self.parent.text = proposedValue
             }
             return true
         }
       }
     }
    
    0 讨论(0)
  • 2020-12-28 19:07

    Solved the issue using UIRepresentable protocol

     struct TestTextfield: UIViewRepresentable {
        @Binding var text: String
        var keyType: UIKeyboardType
        func makeUIView(context: Context) -> UITextField {
            let textfield = UITextField()
          textfield.keyboardType = keyType
            let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: textfield.frame.size.width, height: 44))
            let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(textfield.doneButtonTapped(button:)))
            toolBar.items = [doneButton]
            toolBar.setItems([doneButton], animated: true)
            textfield.inputAccessoryView = toolBar
            return textfield
        }
    
        func updateUIView(_ uiView: UITextField, context: Context) {
            uiView.text = text
    
        }
    }
    
    extension  UITextField{
        @objc func doneButtonTapped(button:UIBarButtonItem) -> Void {
           self.resignFirstResponder()
        }
    
    }
    

    Using in content view

    struct ContentView : View {
    @State var text = ""
    
    var body: some View {
        TestTextfield(text: $text, keyType: UIKeyboardType.phonePad)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 50)
            .overlay(
                RoundedRectangle(cornerRadius: 16)
                    .stroke(Color.blue, lineWidth: 4)
        )
    }
    

    }

    0 讨论(0)
  • 2020-12-28 19:16

    I did it in 5 lines using the SwiftUI-Introspect library! I had a problem that the Representable Text Field did not react in any way to padding and frame. Everything was decided using this library!

    Link: https://github.com/siteline/SwiftUI-Introspect

    import SwiftUI
    import Introspect
    
    struct ContentView : View {
    @State var text = ""
    
    var body: some View {
        TextField("placeHolder", text: $text)
           .keyboardType(.default)
           .introspectTextField { (textField) in
               let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: textField.frame.size.width, height: 44))
               let flexButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
               let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(textField.doneButtonTapped(button:)))
               doneButton.tintColor = .systemPink
               toolBar.items = [flexButton, doneButton]
               toolBar.setItems([flexButton, doneButton], animated: true)
               textField.inputAccessoryView = toolBar
            }
    }
    
    extension  UITextField {
       @objc func doneButtonTapped(button:UIBarButtonItem) -> Void {
          self.resignFirstResponder()
       }
    }
    

    output

    0 讨论(0)
提交回复
热议问题