iOS - 设置具有动态高度的CollectionView标头

时间:2017-06-08 12:14:00

标签: ios uicollectionview uitextview uicollectionviewcell

我有一个带有标题的集合视图,没有单元格。

我将标题大小设置为等于超视图边界,如下所示:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: view.frame.width, height: view.frame.height)
}

此标头中包含UITextView,它也锚定到标题边界(topAnchor,leftAnchor,bottomAnchor和rightAnchor)。

我需要在键盘关闭时将标题锚定到集合视图高度,但在打开键盘时将其固定在键盘顶部,分别更改其大小。

这里的问题在于标题UITextView子视图的文本不断增长且文本在键盘后面。

这是一个显示正在发生的事情的GIF。 黄色视图是标题 白色视图是带有一些填充的TextView。

当我通过键盘时,文字就在它后面 - 如果我可以在没有键盘的情况下将标题固定在屏幕的底部,而当键盘显示效果很好时,可以将标题固定在屏幕的底部。

gif

任何提示? 感谢

编辑ADIIONAL INFO

正如@Aravind所说,只要键盘显示或隐藏,我就会实现Notification监听器。

由于我在Header类中使用UITextView作为子视图,我实现了以下内容:

这是一个帮助我轻松锚定视图的辅助函数:

extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, right: NSLayoutXAxisAnchor?, paddingTop: CGFloat, paddinfLeft: CGFloat, paddingBottom: CGFloat, paddingRight: CGFloat, width: CGFloat, height: CGFloat) {
    translatesAutoresizingMaskIntoConstraints = false
    if let top = top {
        topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
    }
    if let left = left {
        leftAnchor.constraint(equalTo: left, constant: paddinfLeft).isActive = true
    }
    if let bottom = bottom {
        bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
    }
    if let right = right {
        rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true
    }
    if width != 0 {
        widthAnchor.constraint(equalToConstant: width).isActive = true
    }
    if height != 0 {
        heightAnchor.constraint(equalToConstant: height).isActive = true
    }
}
}



override init(frame: CGRect) {
    super.init(frame: frame)

    addSubview(inputTextView)
    inputTextView.delegate = self

    inputTextView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: 0, paddingRight: 12, width: 0, height: 0)

    setupInputTextViewToolbar()


    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillShow(_:)),
        name: NSNotification.Name.UIKeyboardWillShow,
        object: nil)

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(keyboardWillHide(_:)),
        name: NSNotification.Name.UIKeyboardWillHide,
        object: nil)
}

然后显示/隐藏功能

func keyboardWillShow(_ sender:NSNotification){
    guard let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return }
    inputTextView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: keyboardSize.height, paddingRight: 12, width: 0, height: 0)
}

func keyboardWillHide(_ sender:NSNotification){
        self.inputTextView.anchor(top: self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: 0, paddingRight: 12, width: 0, height: 0)
}

show功能正常工作,使文本视图显示剩余的屏幕大小,因此它不会留在键盘后面,所以这么好。

但是当我触发隐藏功能时,它不会再次调整到屏幕底部。

可能导致这种情况的原因是什么?

1 个答案:

答案 0 :(得分:1)

这里是textView的底部约束的出口,并在键盘显示时和隐藏时更改其值,

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow(_:)),
            name: NSNotification.Name.UIKeyboardWillShow,
            object: nil)
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide(_:)),
            name: NSNotification.Name.UIKeyboardWillHide,
            object: nil)

}

   func keyboardWillShow(_ sender:NSNotification){

        let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
        bottomSpace.constant = (keyboardSize?.height)!


    }
    func keyboardWillHide(_ sender:NSNotification){
    bottomSpace.constant = 0
   }