如何在 app-switcher/closer 栏上方设置输入附件视图的约束?

Posted

技术标签:

【中文标题】如何在 app-switcher/closer 栏上方设置输入附件视图的约束?【英文标题】:How to set input accessory view's constraint above app-switcher/closer bar? 【发布时间】:2019-11-02 13:52:08 【问题描述】:

我很难将我的inputAccessoryView 限制在 iPhoneX 屏幕(和其他缺口设备)的底部安全区域上方。我有一个UICollectionViewController,其inputAccessoryView 是一个UIView,其中包含一个UITextView 和2 个UIButtons。基本上布局是用于聊天应用程序。当我运行当前代码时,inputAccessoryView 不会出现在屏幕底部的安全区域上方。它目前锚定在屏幕底部。附上截图。

如您所见,底部的 app-switcher/closer 栏与我的 inputAccessoryView 重叠。我想让 inputAccessoryView 位于上述栏上方。

这是我当前的代码(与约束有关):

class NewMessagesViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout 
    private lazy var inputTextField: UITextField = 
        let textField = UITextField()
        textField.placeholder = "Enter message"
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.delegate = self
        return textField
    ()
    private lazy var inputContainerView: UIView = 
        let margin = view.layoutMarginsGuide
        let safeArea = view.safeAreaInsets

        let containerView = UIView()
        containerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50)
        containerView.backgroundColor = .white

        let uploadImageView = UIImageView()
        uploadImageView.isUserInteractionEnabled = true
        uploadImageView.image = UIImage(named: "image")
        uploadImageView.translatesAutoresizingMaskIntoConstraints = false
        uploadImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleUploadTap)))
        containerView.addSubview(uploadImageView)
        uploadImageView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
        uploadImageView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
        uploadImageView.widthAnchor.constraint(equalToConstant: 44).isActive = true
        uploadImageView.heightAnchor.constraint(equalToConstant: 44).isActive = true

        let sendButton = UIButton(type: .system)
        sendButton.setTitle("Send", for: .normal)
        sendButton.translatesAutoresizingMaskIntoConstraints = false
        sendButton.addTarget(self, action: #selector(sendText), for: .touchUpInside)
        containerView.addSubview(sendButton)
        // x,y,w,h
        sendButton.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
        sendButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
        sendButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
        sendButton.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true

        containerView.addSubview(self.inputTextField)
        self.inputTextField.leftAnchor.constraint(equalTo: uploadImageView.rightAnchor, constant: 8).isActive = true
        self.inputTextField.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
        self.inputTextField.rightAnchor.constraint(equalTo: sendButton.leftAnchor).isActive = true
        self.inputTextField.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true

        let separatorLineView = UIView()
        separatorLineView.backgroundColor = UIColor(red: 220, green: 220, blue: 220)
        separatorLineView.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(separatorLineView)
        separatorLineView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
        separatorLineView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        separatorLineView.widthAnchor.constraint(equalTo: containerView.widthAnchor).isActive = true
        separatorLineView.heightAnchor.constraint(equalToConstant: 1).isActive = true

        return containerView
    ()

    override var inputAccessoryView: UIView? 
        get 
            return inputContainerView
        
    

    override var canBecomeFirstResponder: Bool 
        return true
    

    override func viewDidLoad() 
        super.viewDidLoad()

        self.navigationItem.title =  ticket.subject

        collectionView.keyboardDismissMode = .interactive
    

我尝试将UITextField and UIButton's 底部锚约束约束为等于viewDidLoad() 中的view.layoutMarginsGuide.bottomAnchor,但这只会让我的应用程序崩溃并出现错误:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x28204dac0 "UIImageView:0x107417780.bottom"> and <NSLayoutYAxisAnchor:0x2820270c0 "UILayoutGuide:0x280c8cb60'UIViewLayoutMarginsGuide'.bottom"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'

感谢是否有人可以提供有关如何正确限制应用切换器/关闭栏上方的 inputAccessoryView 的代码 sn-p。

【问题讨论】:

为什么不在安全区域底部插入时让输入视图更高? 能否添加NewMessagesViewController的storyboard截图。 @SGDev 我没有为 NewMessagesViewController 使用故事板 【参考方案1】:

使用 SafeArea 设置 CollectionView 底部约束,这将解决您的问题。

【讨论】:

以上是关于如何在 app-switcher/closer 栏上方设置输入附件视图的约束?的主要内容,如果未能解决你的问题,请参考以下文章

在iOS 7中隐藏导航栏时,如何更改状态栏的颜色?

在H5中如何设置才能让安卓状态栏显示颜色?

Android 如何隐藏ActionBar,保留标题栏

如何在iOS6中停止状态栏覆盖导航栏

如何在导航栏上设置常用栏按钮项

切换侧边栏时如何在导航栏中移动/动画文本值