如果为子视图设置前导和尾随锚点,为什么 UIScrollView 不起作用?
Why UIScrollView don't work if you set leading and trailing anchors for subViews?
示例:
class ViewController: UIViewController {
let labelOne: UIView = {
let label = UIView()
label.backgroundColor = .red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.contentSize = CGSize(width: 2000, height: 2000)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
scrollView.addSubview(labelOne)
labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
}
P.s
我知道如果我将内容视图放在 UIScrollView 中并在该内容中构建视图层次结构会更好,但我真的很想知道为什么会这样
看看这个...
我们设置labelOne
(红色视图):
- 宽度为 1968 磅(每边 2000 减去 16 磅)
- 高度到 100 磅
- 滚动视图
.contentLayoutGuide
的顶部、前导和尾部距顶部、前导和尾部 16 磅
- 距滚动视图底部 1884 点的底部
.contentLayoutGuide
所以:
class ViewController: UIViewController {
let labelOne: UIView = {
let label = UIView()
label.backgroundColor = .red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
// don't set this
//v.contentSize = CGSize(width: 2000, height: 2000)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
scrollView.addSubview(labelOne)
// don't constrain directly to scrollView
//labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
//labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
//labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
//labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
// if we want horizontal scrolling of 2000-pts
// and labelOne to have 16-pts space on each side
labelOne.widthAnchor.constraint(equalToConstant: 2000.0 - 32.0).isActive = true
// labelOne height = 100
labelOne.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
// use scrollView's Content Layout Guide
let g = scrollView.contentLayoutGuide
// labelOne 16-pts from top
labelOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 16.0).isActive = true
// labelOne 16-pts from leading
labelOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0).isActive = true
// labelOne 16-pts from trailing (so we can scroll 2000-pts
labelOne.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0).isActive = true
// if we want vertical scrolling of 2000-pts
// and labelOne to be 100-pts tall with 16-pts on top
// constrain labelOne bottom (2000 - (100 + 16)) from content guide bottom
labelOne.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -(2000.0 - (100.0 + 16.0))).isActive = true
}
}
示例:
class ViewController: UIViewController {
let labelOne: UIView = {
let label = UIView()
label.backgroundColor = .red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.contentSize = CGSize(width: 2000, height: 2000)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
scrollView.addSubview(labelOne)
labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
}
P.s 我知道如果我将内容视图放在 UIScrollView 中并在该内容中构建视图层次结构会更好,但我真的很想知道为什么会这样
看看这个...
我们设置labelOne
(红色视图):
- 宽度为 1968 磅(每边 2000 减去 16 磅)
- 高度到 100 磅
- 滚动视图
.contentLayoutGuide
的顶部、前导和尾部距顶部、前导和尾部 16 磅
- 距滚动视图底部 1884 点的底部
.contentLayoutGuide
所以:
class ViewController: UIViewController {
let labelOne: UIView = {
let label = UIView()
label.backgroundColor = .red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
// don't set this
//v.contentSize = CGSize(width: 2000, height: 2000)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
scrollView.addSubview(labelOne)
// don't constrain directly to scrollView
//labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
//labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
//labelOne.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16).isActive = true
//labelOne.heightAnchor.constraint(equalToConstant: 100).isActive = true
// if we want horizontal scrolling of 2000-pts
// and labelOne to have 16-pts space on each side
labelOne.widthAnchor.constraint(equalToConstant: 2000.0 - 32.0).isActive = true
// labelOne height = 100
labelOne.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
// use scrollView's Content Layout Guide
let g = scrollView.contentLayoutGuide
// labelOne 16-pts from top
labelOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 16.0).isActive = true
// labelOne 16-pts from leading
labelOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0).isActive = true
// labelOne 16-pts from trailing (so we can scroll 2000-pts
labelOne.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0).isActive = true
// if we want vertical scrolling of 2000-pts
// and labelOne to be 100-pts tall with 16-pts on top
// constrain labelOne bottom (2000 - (100 + 16)) from content guide bottom
labelOne.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -(2000.0 - (100.0 + 16.0))).isActive = true
}
}