I'm adding a very large UIView to a UIScrollView, however the scroll view does not scroll to show the whole subview.
When I add a label to the UIScrollView, it does scroll to show that label.
On the actual project I'm working on, I added many views within the scrollView and it is not scrolling at all. This is a simplified example to show my problem:
import UIKit
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.backgroundColor = .blue
scroll.translatesAutoresizingMaskIntoConstraints = false
return scroll
}()
let viewDoesntWork: UIView = {
let view = UIView()
view.backgroundColor = .purple
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let labelWorks: UILabel = {
let label = UILabel()
label.text = "Why this work?"
label.backgroundColor = .green
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
// Add scrollView to view, 20 from edges of view on all sides
view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
// OPTION 1 (does not work):
// Add viewDoesntWork to view, make it much bigger than the scrollView fits
scrollView.addSubview(viewDoesntWork)
viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20).isActive = true
viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 20).isActive = true
viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true
// OPTION 2 (works):
// Add labelWorks to scrollView, and it does scroll to it.
// Uncomment this to see that work.
// scrollView.addSubview(labelWorks)
// labelWorks.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 1000).isActive = true
// labelWorks.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 1000).isActive = true
// labelWorks.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -20).isActive = true
// labelWorks.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -20).isActive = true
}
}
As is, this does not scroll. But, if you comment out the specified section, it does.
Why is this? How can it make it such that adding subViews to the scrollView makes it scroll?
Thanks!
The two things are not at all parallel. You have an example of what works, but in your other example you are not doing that, and that is why it doesn't work. Change:
viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20).isActive = true
viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 20).isActive = true
viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true
To:
viewDoesntWork.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
viewDoesntWork.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
viewDoesntWork.widthAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.heightAnchor.constraint(equalToConstant: 1000).isActive = true
viewDoesntWork.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
viewDoesntWork.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true
The answer of matt causes a [LayoutConstraints] problem in the console here is my simplified Answer
/*
I shortened and simplified your code, I also added some
explanations such that you could understand that's why the code will
seem long
*/
// let's call the viewDoesntWork view1
// first of all you didn't give a frame to the view1
/*
secondly you didn't set the content size(the content size is the
size of the scrollable area) of the scrollView!!
if the scrollView doesn't have a contentSize , it won't scroll
*/
/*
you don't need to set translatesAutoresizingMaskIntoConstraints =
false for labelWorks
Adding UIView to UIScrollView does not change the content size, you
have to set it manually
*/
import UIKit
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.backgroundColor = .blue
scroll.translatesAutoresizingMaskIntoConstraints = false
return scroll
}()
let viewDoesntWork: UIView = {
let view = UIView()
view.backgroundColor = .purple
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let labelWorks: UILabel = {
let label = UILabel()
label.text = "Why this work?"
label.backgroundColor = .green
return label
}()
//In this function we set up the frame and other stuffs of the
//subviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// let's give it a content size
scrollView.contentSize = CGSize(width:view.frame.size.width , height: 1000)
viewDoesntWork.frame = CGRect(x: 20, y: 20,
width:view.frame.size.width , height: 800)
/*
viewDoesntWork.topAnchor.constraint(equalTo:
scrollView.topAnchor, constant: 20).isActive = true isn't
necessary anymore
since we set the y = 20 , the same goes for letfAnchor and x = 20
*/
/*
In my opinion , you don't need to set constraints for the size
of the viewDoesntWork
*/
labelWorks.frame = CGRect(x:view.center.x , y:
viewDoesntWork.frame.size.height + 20 + 40 , width:120,
height: 20)
// I added your label below the viewDoesntWork
/*
you don't need to set constraints, these are just some
calculations since you know the content size
*/
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
// Add scrollView to view, 20 from edges of view on all sides
view.addSubview(scrollView)
scrollView.addSubview(viewDoesntWork)
scrollView.addSubview(labelWorks)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant:
20).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant:
20).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant:
-20).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant:
-20).isActive = true
}
}
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.