将 UIView 添加到 UIScrollView 不会改变内容大小?
Adding UIView to UIScrollView does not change content size?
我正在向 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
}
}
照原样,这不会滚动。但是,如果您注释掉指定的部分,它会。
这是为什么?如何让它在 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
}
}
我正在向 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
}
}
照原样,这不会滚动。但是,如果您注释掉指定的部分,它会。
这是为什么?如何让它在 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
}
}