View at the bottom in a UIScrollView, with AutoLayout
Solution 1
Fairly easy to do with Auto-Layout only... no code required.
The key is to use a "content view" to hold the elements, and a greater-than-or-equal
constraint between your "bottom" element and your "footer" view.
In this image, yellow is the main view, green is the scroll view, blue is the content view, the labels are gray and the footer view is pink.
- Start with a fresh view controller
- add a scroll view, normal constraints (I used
20
all the way around, so we can see the frame) - add a
UIView
to the scrollView - this will be our "content view" - constrain contentView Top/Bottom/Leading/Trailing all equal to
0
to the scrollView - constrain both the Width and Height of the contentView equal to the scrollView
- add your elements - here I used 3 labels
- constrain the labels as usual... I used:
- LabelA - Top/Leading/Trailing all at
20
, vertical spacing to LabelB of60
- LabelB - Leading/Trailing at
20
, vertical spacing to LabelC of60
- LabelC - Leading/Trailing at
20
- LabelA - Top/Leading/Trailing all at
- LabelC is also set to
Number of Lines: 0
so it will expand with multiple lines of text - Add a
UIView
as a "footer view" (I stuck a label in it) - constrain the footerView Leading/Trailing/Bottom all at
20
(so we can see the frame) - either set a Height constraint on footerView, or use its content to constrain its height
- add a Vertical Spacing constraint from LabelC to footerView, and set it to
>= 40
- last step, change the Height constraint of contentView to
Priority: 250
Now, as you expand/contract the height of LabelC, the footerView will keep at least 40-pts of vertical space. When LabelC gets big enough to "push" footerView below the bottom, scrollView will become scrollable.
Results:
Solution 2
you need to check ContentSize of scrollView and modify FooterView Top Constraint with the required Value
My class code
import UIKit
class scrollViewDrag: UIViewController
{
/// ScrollView Outlet
@IBOutlet weak var mainScrollView: UIScrollView!
/// Footer View top spacing constraint
@IBOutlet weak var footerViewTopConstraint: NSLayoutConstraint!
/// Used for ScrollView Height
var screenHeight = CGFloat()
/// Did Load
override func viewDidLoad() {
super.viewDidLoad()
}
/// Function used to check for height
func checkForHeight(){
/// Get scrollView Height
screenHeight = mainScrollView.frame.size.height
/// Check contentSize Height ?
if mainScrollView.contentSize.height >= screenHeight {
/// When ScrollView is having height greater than your scrollView Height
/// Footer will scroll along other Views
}
else{
/// Issue Case
let spacingValue = screenHeight-mainScrollView.contentSize.height
footerViewTopConstraint.constant = spacingValue
}
}
/// Call the height function in DidAppear
override func viewDidAppear(_ animated: Bool) {
checkForHeight()
}
}
Storyboard
I had used Four View with Equal Heights And at last a footerView is attached as Fourth View
FooterView Top Constraint
Top constraint used as footerViewTopConstraint
Output
Case 1 - Size is greater than scrollView Height
Case 2 - Expected Output
Coconuts
Updated on July 18, 2022Comments
-
Coconuts almost 2 years
I'm setting up content in a scroll view with autolayout. The objects in the scrollview are pinned top-to-bottom to the previous one, so that they are under one another. I have a footer view that is added at the end, below these objects.
Here's the catch: when there's few content, the contentView will be smaller than the screen height, so the footer view will appear somewhere in the middle of the screen (which is the normal behavior). But I'd like to prevent that, and make the view stay somewhere at the bottom.
In other words, I would like to setup a double constraint like:
Put this view below all the objects in the scrollview AND keep this view at a distance of max [some number] of the bottom of the screen
In a way that both constraints are always satisfied:
- If the height of the content is bigger than the screen, then the view appears at the bottom, after scrolling down
- If the height is smaller, then the view is "pinned" to the bottom of the screen, leaving a space relatively big between the bottom of the content and the top of this view
How can I achieve that with AutoLayout?
-
DonMag almost 6 yearsSee my answer for an Auto-Layout-only solution.
-
Coconuts almost 6 yearsThis is indeed working! Although I thought there would be a way to achieve that using only constraints, without manual computation.
-
DonMag almost 6 yearsHmm... I don't think I missed any steps... You can get my storyboard here - see what's different, if anything: gist.github.com/DonMag/7576d0710163ae4f53f7508c1fed35f6
-
Coconuts almost 6 yearsThis is exactly what I wanted. Works great. Thanks a lot!
-
Bartłomiej Semańczyk about 5 yearsMagic answer, works like a charm;) A bottle of wine for that guy🚀
-
Pablo Blanco over 4 yearsIt worked also for me, nice answer, easy to apply, working properly. TOP
-
Guven over 4 yearsTextbook explanation backed by crafted images. Thank you so much!
-
Bogdan Razvan over 4 yearsWorks great! I was looking for a solution to this problem for so long! Thank you for taking the time to explain it.