Damiano Miazzi
Damiano Miazzi

Reputation: 2315

swiftUI how to have search button on keyboard

In SwiftUI I have a simple search TextField where the user type something to be searched and a Button search.

I just want to add the option to have the button Search in the lower right corner of the Keyboard (I saw it in some application)

how can I do that?

Upvotes: 3

Views: 6235

Answers (3)

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119310

iOS 15

You can change the return key for each textField with a simple modifier called: .submitLabel that takes the return key type and you should pass .search. Take a look at the following example:

enter image description here

Also, as you can see, you can have a callback to handle the return key press action just like the old textFieldShouldReturn function that is accessible by '.onSubmit' modifier.

Upvotes: 19

Farshid roohi
Farshid roohi

Reputation: 768

Simple Use SearchTextField.swift

import SwiftUI
import UIKit

class UIKitTextField: UITextField, UITextFieldDelegate {
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        delegate = self
    }
    
    required override init(frame: CGRect) {
        super.init(frame: frame)
        delegate = self
        self.setContentHuggingPriority(.defaultHigh, for: .vertical)
    }
    
    var action:(() -> Void)? = nil
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.action?()
        
        if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
            nextField.becomeFirstResponder()
        } else {
            textField.resignFirstResponder()
            return true;
        }
        return false
    }
    
}

struct SearchTextField : UIViewRepresentable {
    
    @Binding var text: String
    var action:() -> Void
    
    func makeCoordinator() -> SearchTextField.Coordinator {
        return Coordinator(value: self)
    }
    
    class Coordinator: NSObject,UITextFieldDelegate {
        
        var parent:SearchTextField
        
        init(value: SearchTextField) {
            self.parent = value
        }
        
        @objc func textFieldEditingChanged(_ sender: UIKitTextField) {
            self.parent.text = sender.text ?? ""
        }
    }
    
    func makeUIView(context: Context) -> UIKitTextField {
        
        let textfield = UIKitTextField(frame: .zero)
        
        textfield.addTarget(context.coordinator, action: #selector(Coordinator.textFieldEditingChanged(_:)), for: .editingChanged)
        
        textfield.text = self.text
        textfield.placeholder = "search"
        textfield.borderStyle = .none
        textfield.returnKeyType = .search
        textfield.action = self.action
        
        return textfield
    }
    
    func updateUIView(_ uiView: UIKitTextField,
                      context: Context) {
        uiView.text = self.text
    }
    
}

Use :

  SearchTextField(text: self.$searchKey) {
      self.search(key: self.searchKey)
      // or...
   }

Upvotes: 1

arata
arata

Reputation: 910

If I understand correctly you want to change the UIReturnKeyType. In that case you have to use UIKit since there isn't yet any option to change the type of return key in SwiftUI. To do this, you have to make a custom TextField using UIIKit and then modify it the way you like.

Also keep in mind that the UIReturnKeyType enum is under discussion and may replace with a different implementation.

// MARK: Custom TextField
struct TextFieldTyped: UIViewRepresentable {
    let keyboardType: UIKeyboardType
    let returnVal: UIReturnKeyType
    let tag: Int
    @Binding var text: String
    @Binding var isfocusAble: [Bool]

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.keyboardType = self.keyboardType
        textField.returnKeyType = self.returnVal
        textField.tag = self.tag
        textField.delegate = context.coordinator
        textField.autocorrectionType = .no

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        if isfocusAble[tag] {
            uiView.becomeFirstResponder()
        } else {
            uiView.resignFirstResponder()
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: TextFieldTyped

        init(_ textField: TextFieldTyped) {
            self.parent = textField
        }

        func updatefocus(textfield: UITextField) {
            textfield.becomeFirstResponder()
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {

            if parent.tag == 0 {
                parent.isfocusAble = [false, true]
                parent.text = textField.text ?? ""
            } else if parent.tag == 1 {
                parent.isfocusAble = [false, false]
                parent.text = textField.text ?? ""
         }
        return true
        }

    }
}

And you can use it like this: (Change the returnVal to .search in your case.)

struct CustomeKT: View {

    @State var myTextForTX = ""
    @State var focused: [Bool] = [false, true]

    var body: some View {
        TextFieldTyped(keyboardType: .default, returnVal: .search, tag: 0, text: self.$myTextForTX, isfocusAble: self.$focused)
    }
}

Upvotes: 3

Related Questions