swiftuitextfielduitextviewinputaccessoryviewinputview

Show uitextview with keypad and toolbar when editing textfield


enter image description here

What is the right approach to achieve what you see in the gif? It's a tableview with textfields. When you tap a textfield, a textview shows up with it's keypad. I have a tableview with a custom tableviewcell with a textfield(valueTextField). And in cellforrow i set the inputview of the textfield to a UITextView. When i press the textfield, the textview is supposed to show the toolbar on top (with a "Done" button) but no toolbar shows. When i tap the textview, still no toolbar.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! EditProfileTableViewCell
    cell.isUserInteractionEnabled = true
    cell.valueTextField.isUserInteractionEnabled = true
    cell.valueTextField.delegate = self
    toolBar = UIToolbar()
    toolBar.sizeToFit()

    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(editorDone))
    toolBar.setItems([doneButton], animated: false)

    editorTextView = UITextView(frame: CGRect(x:0, y:0, width:view.bounds.width, height:view.bounds.height))
    cell.valueTextField.inputAccessoryView = toolBar
        cell.valueTextField.inputView = editorTextView

    return cell
}

enter image description here


Solution

  • The example you show is simply using a UINavigationController to navigate to a separate UIViewController when the cell is tapped. In this view controller, the UITextField will be handled something like this.

    // View controller subclass conforming to UITextFieldDelegate protocol
    class MyDetailViewController: UIViewController, UITextFieldDelegate {
    
        // Set an IB Outlet to the text field in storyboard
        @IBOutlet myTextField: UITextField!
    
        override viewDidLoad() {
            myTextField.delegate = self
    
            // ToolBar
            let toolBar = UIToolbar()
            // Optional styling
            toolBar.barStyle = .default
            toolBar.isTranslucent = true
            toolBar.tintColor = .black
            toolBar.layer.borderWidth = 0
    
            toolBar.sizeToFit()
    
            // Buttons
            let buttonOne = BarButtonItem(title: "One", style: .plain, target: self, action: #selector(yourSelectorOne(_:)))
            let buttonTwo = BarButtonItem(title: "One", style: .plain, target: self, action: #selector(yourSelectorTwo(_:)))
    
            let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    
           toolBar.setItems([buttonOne, spacer, buttonTwo], animated: false)
           toolBar.isUserInteractionEnabled = true
           textField.inputAccessoryView = toolBar
        }
    }
    

    This will create two buttons, one on the left and one on the right of the toolbar. The type of keyboard can be set in Interface Builder.

    To get this by tapping on the text field in the cell directly, without navigating to a new view controller, you could set your custom UITableViewCell subclass as the text field delegate.

    Note that you will need to provide method stubs to conform to the UITextFieldDelegate protocol. These are not essential for this example so I have omitted them. XCode will offer to populate them for you.