- I've got a scroll view (diagram: words) that is much longer than the device height
- At the bottom of the scroll view is some bottom content (diagram: french press) with a different background colour.
- To separate the bottom content from the words, I've created a 1pt high UIView to act as a border (diagram: red line)
- I have a button that sits on the bottom of the device, outside the scroll view (the scroll view is
device.height - button.height
). This button's background colour matches the bottom content's background colour.
The different background colours look pretty wonky without something separating the bottom button from the content view, so while the bottom content is NOT visible, I'd like the border to be sticky, and appear to be sitting above the bottom button (diagram: red line).
A small note: I'm using AutoLayout in IB, but I have an IBOutlet created for the border constraint that I can easily manipulate in code.
Here is a lib that does the job:
https://github.com/ericcastro/ECStretchableHeaderView
(it works with UItableView in the sample but implementation is based on UIScrollview)
You have to update the code by changing the logic:
Here the view is on the top, but the whole principle is there!
You could create two borders.
The first one is the dynamic border at the top of the bottom content in the scroll view.
The second one is the sticky border at the top of the button outside of the scroll view.
The second border should be hidden when the first border is visible. In order to do this, you should register a UIScrollViewDelegate
. Implement the method scrollViewDidScroll(_:)
. Just check if the first border is above the second. This can be done with something like this:
if firstBorder.frame.origin.y < scrollView.contentOffset.y + scrollView.frame.height {
// firstBorder is on the screen, hide the secondBorder...
secondBorder.hidden = true
} else {
secondBorder.hidden = false
}
This may be not 100% correct for you, because it's not clear whether your UIScrollView
ends above the button or whether they are overlapping. Adjust it if the border hides too early or too late.
If your button is transparent, you should also hide the first border if it is not shown, because it could be under the button. Then just add the lines firstBorder.hidden = false
and firstBorder.hidden = true
to the code.
I'd take these steps:
- Put the button in a view that's outside of the
scrollView
.
- Put the awesome bottom content (which I thought was a picture of Bender's head) in the same view that the button is in, and constrain it to the top, left and right edges.
- Set the bottom dimension of the scroll view's content insets to be equal to the height of the awesome bottom content view. This will tell the scroll view that it's ok to scroll down that many pixels below the actual end of the scrollable content.
- Add a
UIScrollViewDelegate
to the scroll view that implements, at the very least, scrollViewDidScroll(_)
. In this method, check the bottom-most position of the scrolling content. If that position falls somewhere in the bottom content inset that you set in step #3, stretch or otherwise reposition your awesome bottom content vertically that same amount.
If I have time, I'll whip up a sample that does just this.
There are at least two simple solutions that comes to my mind firstly.
The key is to find cross point:
Content size value where red line on scroll view comes out from below of the button or goes in below the button.
Option 1:
Add another red line on the top of the button and hide/show (hidden property) in the scrollViewDidScroll when the content size value approaches cross point
Option 2:
Whether content size value approaches cross point remove constraints and change superview of the red line from scrollview to button or conversely. Re-add constraints for specific superview. Obviously you need to do that in the code.