iPhone X how to handle View Controller inputAccessoryView?

前端 未结 15 2721
长情又很酷
长情又很酷 2020-11-30 00:43

I have a messaging app that has the typical UI design of a text field at the bottom of a full screen table view. I am setting that text field to be the view controller\'s

15条回答
  •  感情败类
    2020-11-30 01:17

    After much research and trials, this seems to be a working solution for trying to use UIToolbar with a text input's inputAccessoryView. (Most of the existing solutions are for using fixed accessory view instead of assigning it to a text view (and hiding it when the keyboard is closed).)

    The code is inspired by https://stackoverflow.com/a/46510833/2603230. Basically, we first create a custom view that has a toolbar subview:

    class CustomInputAccessoryWithToolbarView: UIView {
        public var toolbar: UIToolbar!
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            // https://stackoverflow.com/a/58524360/2603230
            toolbar = UIToolbar(frame: frame)
    
            // Below is adopted from https://stackoverflow.com/a/46510833/2603230
            self.addSubview(toolbar)
    
            self.autoresizingMask = .flexibleHeight
    
            toolbar.translatesAutoresizingMaskIntoConstraints = false
            toolbar.leadingAnchor.constraint(
                equalTo: self.leadingAnchor,
                constant: 0
            ).isActive = true
            toolbar.trailingAnchor.constraint(
                equalTo: self.trailingAnchor,
                constant: 0
            ).isActive = true
            toolbar.topAnchor.constraint(
                equalTo: self.topAnchor,
                constant: 0
            ).isActive = true
            // This is the important part:
            if #available(iOS 11.0, *) {
                toolbar.bottomAnchor.constraint(
                    equalTo: self.safeAreaLayoutGuide.bottomAnchor,
                    constant: 0
                ).isActive = true
            } else {
                toolbar.bottomAnchor.constraint(
                    equalTo: self.layoutMarginsGuide.bottomAnchor,
                    constant: 0
                ).isActive = true
            }
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        // https://stackoverflow.com/a/46510833/2603230
        // This is needed so that the inputAccesoryView is properly sized from the auto layout constraints.
        // Actual value is not important.
        override var intrinsicContentSize: CGSize {
            return CGSize.zero
        }
    }
    

    Then you can set it as an inputAccessoryView for a text input normally: (You should specify the frame size to avoid the warnings seen in UIToolbar with UIBarButtonItem LayoutConstraint issue)

    let myAccessoryView = CustomInputAccessoryWithToolbarView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 44))
    textView.inputAccessoryView = myAccessoryView
    

    When you want to interact with the toolbar (e.g., set items on the toolbar), you can simply refer to the toolbar variable:

    myAccessoryView.toolbar.setItems(myToolbarItems, animated: true)
    

    Demo: (with hardware keyboard / Command+K in simulator)

    Before:

    After:

提交回复
热议问题