I am trying to get an inputAccessoryView working correctly. Namely, I want to be able to display, in this case, a UIToolbar in two possible states:
- Above the keyboard - standard and expected behavior
- At the bottom of the screen when the keyboard is dismissed (e.g. command + K in the simulator) - and in such instances, have the bottomAnchor respect the bottom safeAreaLayoutGuide.
I've researched this topic extensively but every suggestion I can find has a bunch of workarounds that don't seem to align with Apple engineering's suggested solution. Based on an openradar ticket, Apple engineering proposed this solution be approached as follows:
It’s your responsibility to respect the input accessory view’s safeAreaInsets. We designed it this way so developers could provide a background view (i.e., see Safari’s Find on Page input accessory view) and lay out the content view with respect to safeAreaInsets. This is fairly straightforward to accomplish. Have a view hierarchy where you have a container view and a content view. The container view can have a background color or a background view that encompasses its entire bounds, and it lays out it’s content view based on safeAreaInsets. If you’re using autolayout, this is as simple as setting the content view’s bottomAnchor to be equal to it’s superview’s safeAreaLayoutGuide.
The link for the above is: http://www.openradar.me/34411433
I have therefore constructed a simple xCode project (iOS App template) that has the following code:
class ViewController: UIViewController {
    
    var field = UITextField()
    var containerView = UIView()
    var contentView = UIView()
    var toolbar = UIToolbar()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // TEXTFIELD
        field = UITextField(frame: CGRect(x: 20, y: 100, width: view.frame.size.width, height: 50))
        field.placeholder = "Enter name..."
        field.backgroundColor = .secondarySystemBackground
        field.inputAccessoryView = containerView
        view.addSubview(field)
        
        // CONTAINER VIEW
        containerView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
        containerView.backgroundColor = .systemYellow
        containerView.translatesAutoresizingMaskIntoConstraints = false
                
        // CONTENT VIEW
        contentView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
        contentView.backgroundColor = .systemPink
        contentView.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(contentView)
        
        // TOOLBAR
        toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50))
        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(didTapDone))
        toolbar.setItems([flexibleSpace, doneButton], animated: true)
        toolbar.backgroundColor = .systemGreen
        toolbar.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(toolbar)
        
        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: containerView.topAnchor),
            contentView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: contentView.superview!.safeAreaLayoutGuide.bottomAnchor),
            toolbar.topAnchor.constraint(equalTo: contentView.topAnchor),
            toolbar.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            toolbar.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            toolbar.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
        ])
    }
    
    
    @objc private func didTapDone() {
        print("done tapped")
    }
}
The result works whilst the keyboard is visible but doesn't once the keyboard is dimissed:
I've played around with the heights of the various views with mixed results and making the container view frame height larger (e.g. 100), does show the toolbar when the keyboard is collapsed, it also makes the toolbar too tall for when the keyboard is visible.
Clearly I'm making some auto layout constraint issues but I can't work out and would appreciate any feedback that provides a working solution aligned with Apple's recommendation.
Thanks in advance.


