我正在向UIScrollView添加一个非常大的UIView,但是滚动视图不会滚动显示整个子视图。
当我在UIScrollView中添加标签时,它会滚动显示该标签。
在我正在进行的实际项目中,我在scrollView中添加了许多视图,但它根本没有滚动。这是一个简化的例子来说明我的问题:
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
}
}
按原样,它不会滚动。但是,如果您注释掉指定的部分,它确实会注释掉。
为什么会这样?如何将subViews添加到scrollView中使其滚动?
谢谢!
这两件事根本不平行。你有一个有效的例子,但在另一个例子中,你没有这样做,这就是为什么不起作用。更改:
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
收件人:
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
matt的答案导致控制台中的[LayoutConstraints]问题这是我的简化答案
/*
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
}
}