简体   繁体   中英

iOS - Set CollectionView Header with dynamic height

I have a collection view with a Header and no cells.

I've set the header size to be equal to the superview bounds as following:

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

This header has a UITextView in it, which is anchored, as well, to the headers bounds (topAnchor, leftAnchor, bottomAnchor and rightAnchor).

I need the header to be anchored to the collection view height when the keyboard is closed, but anchored to the top of the keyboard when this one is opened, changing its size respectively.

The problem here lies when the text of the headers UITextView subview keeps growing and the text goes behind the keyboard.

Here's a GIF showing what's happening. The yellow view is the Header The white view is the TextView with some padding.

When I pass the keyboard the text goes behind it - if I could anchor the header to the bottom of the screen when there's no keyboard and to the bottom of the keyboard when its shown would be great.

gif

Any hint? Thanks

EDIT ADICIONAL INFO

As @Aravind said I've implemented the Notification listener to fire whenever the keyboard shows or hides.

Since I'm using the UITextView inside the Header class as its subview I've implemented the following:

This is an helper function to anchor my views easily:

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)
}

Then the Show/Hide functions

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)
}

The show function works properly and makes the text view to the remaining screen size so it doesn't stay behind the keyboard, so far so good.

But when I fire the hide function it doesn't resize again to the bottom of the screen.

What maybe causing this?

Here make an outlet of the textView's bottom constraint and change its value when keyboard shows up and when it hides like,

    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
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM