0

I'm trying to make custom inputAccessoryView contain UITextField and docking it bottom like chat application

but if i didn't use canBecomeFirstResponder = true inputAccessoryView are hidden(?)

this is my code

class MainVC: UITableViewController {
  lazy var inputTextFieldContainer: UIView = {
    // custom inputAccessoryView
  }()

  override func viewDidLoad(){
    super.viewDidLoad()
  }

  override var inputAccessoryView: UIView? {
      get{
          return containerView
      }
  }

  override var canBecomeFirstResponder: Bool {
      get {
          return true
      }
  }
}

how canBecomeFirstResponder bring custom inputAccessoryView

i read about UIResponder and responder chain on Apple docs

but i couldn't match that concept to this issue.

They said UIResponder will handle the events and i make my MainVC become first responder by canBecomeFirstResponder = true

and inputAccessoryView are shown

but what is the exact event in this case and situation

PrepareFor
  • 2,448
  • 6
  • 22
  • 36
  • You are abusing `inputAccessoryView` for something that it was not intended. You cannot have a working input in `inputAccessoryView`. – Sulthan Mar 31 '18 at 15:49

1 Answers1

1

Since your code inherits from UITableViewController here a complete example with it:

Start with defining a accessory view. Since you mentioned as an example a chat app it could be a textfield and a send button:

class SendMessageView: UIView {

    private let textField = UITextField()
    private let sendButton = UIButton()

    init() {
        super.init(frame: CGRect.zero)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) not implemented")
    }

    private func setup() {
        sendButton.setTitle("Send", for: UIControlState.normal)
        sendButton.setTitleColor(UIColor.blue, for: UIControlState.normal)
        self.addSubview(textField)
        self.addSubview(sendButton)

        self.backgroundColor = UIColor.groupTableViewBackground
        textField.backgroundColor = UIColor.white

        self.autoresizingMask = .flexibleHeight
        textField.translatesAutoresizingMaskIntoConstraints = false
        sendButton.translatesAutoresizingMaskIntoConstraints = false

        textField.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
        textField.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16).isActive = true

        sendButton.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 8).isActive = true
        sendButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16).isActive = true
        sendButton.centerYAnchor.constraint(equalTo: textField.centerYAnchor).isActive = true
    }

    override var intrinsicContentSize: CGSize {
        let contentHeight = self.textField.intrinsicContentSize.height + 16
        return CGSize(width: UIScreen.main.bounds.width, height: contentHeight)
    }
}

Next you need a custom UITableView which uses our accessory view:

class CustomTableView: UITableView {

    private let sendMessageView = SendMessageView()

    override var canBecomeFirstResponder: Bool {
        return true
    }

    override var inputAccessoryView: UIView? {
        return self.sendMessageView
    }
}

Finally one could define a TableViewController using this custom table view:

class TableViewController: UITableViewController {

    override func loadView() {
        self.tableView = CustomTableView()
        self.view = self.tableView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.becomeFirstResponder()
    }

    ...

The result would look like this:

[input accessory view[1]

Stephan Schlecht
  • 26,556
  • 1
  • 33
  • 47