sticky header with scrollView and stackview

1.9k views Asked by At

I know that the sticky header is not a new thing to ask advice on, but still...

I am trying to create a sticky header (UIImageView) and the scrolling part (UIScrollView with a UIStackView in it)

Im using the scrollViewDidScroll method from the UIScrolLViewDelegate. The only problem is, that when I scroll the view up, I am not only decreasing the height of the header view, but also scrolling the content of the stack view. So when I scroll further up, you still can see the header view, but the top content of the scroll view disappears by scrolling.

Can this be solved somehow that when I scroll up, the content of the stack view is scrolling up and not also disappearing? And starts disappearing when the header view disappears?

Thank you

1

There are 1 answers

3
DarkByte On

The easiest way to do this is to use a table view. Your sticky header is the table's first section header, while the scrolling part is the second section.

If you can't use a table, for whatever reason, then you have to mess around with the scroll view's content offset. When the contentOffset.y is growing (but not beyond your header's height), reset it to 0 and decrease the header's height accordingly. After the header's height is 0, stop messing with contentOffset - until you come back and the contentOffset.y wants to go into negatives.

P.S. the second solution requires you to enable bouncing on the scroll view. Otherwise, the header will be hidden, but won't show again (unless you reset the controller)

L.E. Some (old) code for my second solution:

let headerHeight = self.headerView.height
self.scrollHandler = {
    var offset = self.detailsTable.contentOffset

    self.headerTopConstraint.constant -= offset.y
    if self.headerTopConstraint.constant < -headerHeight {
        self.headerTopConstraint.constant = -headerHeight

        let size = self.detailsTable.contentSize
        if offset.y + self.detailsTable.frame.height > size.height {
            offset.y = size.height - self.detailsTable.frame.height
        }

        self.detailsTable.contentOffset = offset
    }
    else {
        if self.headerTopConstraint.constant > 0 {
            self.headerTopConstraint.constant = 0
        }
        self.detailsTable.contentOffset = CGPointZero
    }
}

Please note that my code moved the header upwards to hide it. As far as I understood, you just have to change the header's height (by the same amount I move it upwards).