Calculating contentSize for UIScrollView when using Auto Layout
Solution 1
Giving content size programatically is not good way. The below solution which will work using autolayout, dont need to set content size at all. It will calculate as per how many UI fields added to view.
Step 1 :
Add Scrollview to view in storyboard and add leading, trailing, top and bottom constraints (All values are zero).
Step 2 :
Don't add directly views which you need on directly scrollview, First add one view to scrollview (that will be our content view for all UI elements). Add below constraints to this view.
1) Leading, trailing, top and bottom constraints (All values are zero).
2) Add equal height, equal width to Main view (i.e. which contains scrollview). For equal height set priority to low. (This is the important step for setting content size).
3) Height of this content view will be according to the number of views added to the view. let say if you added last view is one label and his Y position is 420 and height is 20 then your content view will be 440.
Step 3 : Add constraints to all of views which you added within content view as per your requirement.
For reference :
I hope this will definitely help you.
Solution 2
Though I finally got to solve this issue and make things work. I noticed that all I could find on the net as related answers was directed to storyboard users. But nothing to do it programmatically that I could put my hands on.
So I decided to make an extremely simple demo app to show how this can be achieved. I hope it will be useful to someone at some point.
Here is the address to get it on GitHub: https://github.com/zaxonus/AutoLayScroll
Solution 3
I also used constraints programmatically to dynamically modify UIScrollView's contentSize . I pretty much followed Shrikant's instructions but for step 2.1, I set centerX to the scrollViews.centerX rather than set the leading and trailing margins (No idea why the former works, while the latter doesn't). Then as a last step, after adding the final subview, I did the following:
contentView.layoutIfNeeded() //set a frame based on constraints
scrollView.contentSize = CGSize(width: contentView.frame.width, height: contentView.frame.height)
Hope this helps somebody in the future.
Solution 4
All you need to do is to make sure that the first subview's top anchor is constrained to the scrollView's top anchor and the last subview's bottom anchor is constrained to the scrollView's bottom anchor
Solution 5
If you don't want to use storyboards, and just use constraints, you can follow the guide here
https://redflowerinc.com/implement-uiscrollview-using-constraints-no-need-to-use-content-size/
Use can use bottom anchor and pin your views to the scroll view. By using constraints you don't need to use content size.
Michel
I am currently developing iOS software, mainly using Swift. With a total of about 20 apps on the appStore, the main ones being related to language learning. For some examples see: http://www.sofisfun.net/Language/ and http://www.sofisfun.net/Calculators/ I recently got to work on Heroku to port some projects from the Parse.com site to open source Parse-Server, that got me on the way to get my hands on Node.JS where I built this little prime number site to get familiar with the environment. And I more recently got interested in Clojure, where I built this as a trial project.
Updated on August 06, 2021Comments
-
Michel over 2 years
Here is a quick question about something which works, but could be written much better. I have a
UIScrollView
and a list of objects laid out inside, one under the other. Everything is done duringviewDidLoad()
and the placement of the objects usesAuto Layout
. Here is what I do to set thecontentSize
height of theUIScrollView
to its appropriate value.override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) globalView.contentSize = CGSize(width: globalView.frame.width, height: globalView.frame.height * 1.59) }
It works, but the arbitrary value 1.59 has obviously been decided by me trying a few possible values. What is the proper way to compute the contentSize in such a case? I am doing everything programmatically. Searching the net didn't lead me to any simple and clear answer, so eventhough it may be a somewhat duplicate question I decided to reformulate it.