iPhone X how to handle View Controller inputAccessoryView?

前端 未结 15 2645
长情又很酷
长情又很酷 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:21

    Solution that worked for me without workarounds:

    I'm using UIInputViewController for providing input accessory view by overriding inputAccessoryViewController property instead of inputAccessoryView in the "main" view controller.

    UIInputViewController's inputView is set to my custom input view (subclass of UIInputView).

    What actually did the trick for me is setting allowsSelfSizing property of my UIInputView to true. The constraints inside input view use safe area and are set up in a way that defines total view's height (similar to autoresizing table view cells).

    0 讨论(0)
  • 2020-11-30 01:24

    Just add one extension for JSQMessagesInputToolbar

    extension JSQMessagesInputToolbar {
        override open func didMoveToWindow() {
            super.didMoveToWindow()
            if #available(iOS 11.0, *) {
                if self.window?.safeAreaLayoutGuide != nil {
                self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow((self.window?.safeAreaLayoutGuide.bottomAnchor)!,
                                                                                multiplier: 1.0).isActive = true
                }
            }
         }
    }
    

    duplicate : jsqmessageviewcontroller ios11 toolbar

    0 讨论(0)
  • 2020-11-30 01:25

    From code (Swift 4). Idea - monitoring layoutMarginsDidChange event and adjusting intrinsicContentSize.

    public final class AutoSuggestionView: UIView {
    
       private lazy var tableView = UITableView(frame: CGRect(), style: .plain)
       private var bottomConstraint: NSLayoutConstraint?
       var streetSuggestions = [String]() {
          didSet {
             if streetSuggestions != oldValue {
                updateUI()
             }
          }
       }
       var handleSelected: ((String) -> Void)?
    
       public override func initializeView() {
          addSubview(tableView)
          setupUI()
          setupLayout()
          // ...
          updateUI()
       }
    
       public override var intrinsicContentSize: CGSize {
          let size = super.intrinsicContentSize
          let numRowsToShow = 3
          let suggestionsHeight = tableView.rowHeight * CGFloat(min(numRowsToShow, tableView.numberOfRows(inSection: 0)))
          //! Explicitly used constraint instead of layoutMargins
          return CGSize(width: size.width,
                        height: suggestionsHeight + (bottomConstraint?.constant ?? 0))
       }
    
       public override func layoutMarginsDidChange() {
          super.layoutMarginsDidChange()
          bottomConstraint?.constant = layoutMargins.bottom
          invalidateIntrinsicContentSize()
       }
    }
    
    extension AutoSuggestionView {
    
       private func updateUI() {
          backgroundColor = streetSuggestions.isEmpty ? .clear : .white
          invalidateIntrinsicContentSize()
          tableView.reloadData()
       }
    
       private func setupLayout() {
    
          let constraint0 = trailingAnchor.constraint(equalTo: tableView.trailingAnchor)
          let constraint1 = tableView.leadingAnchor.constraint(equalTo: leadingAnchor)
          let constraint2 = tableView.topAnchor.constraint(equalTo: topAnchor)
          //! Used bottomAnchor instead of layoutMarginGuide.bottomAnchor
          let constraint3 = bottomAnchor.constraint(equalTo: tableView.bottomAnchor)
          bottomConstraint = constraint3
          NSLayoutConstraint.activate([constraint0, constraint1, constraint2, constraint3])
       }
    }
    

    Usage:

    let autoSuggestionView = AutoSuggestionView()
    // ...
    textField.inputAccessoryView = autoSuggestionView
    

    Result:

    0 讨论(0)
  • 2020-11-30 01:26

    -- For those who are using the JSQMessagesViewController lib --

    I am proposing a fixed fork based on the JSQ latest develop branch commit.

    It is using the didMoveToWindow solution (from @jki I believe?). Not ideal but worth to try while waiting for Apple's answer about inputAccessoryView's safe area layout guide attachment, or any other better fix.

    You can add this to your Podfile, replacing the previous JSQ line:

    pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true
    
    0 讨论(0)
  • 2020-11-30 01:27

    In Xib, find a right constraint at the bottom of your design, and set item to Safe Area instead of Superview:

    Before:

    Fix:

    After:

    0 讨论(0)
  • 2020-11-30 01:27

    Seems it's an iOS bug, and there is a rdar issue for it: inputAccessoryViews should respect safe area inset with external keyboard on iPhone X

    I guess this should be fixed in iOS update when iPhone X will come up.

    0 讨论(0)
提交回复
热议问题