UIScrollView 中子 View 的布局
如上所示,scroll 为屏幕高度,并透过了顶部和底部的 Bar。
若是相对于 frameLayoutGuide
布局
let topView = UIView.init()
topView.backgroundColor = .blue
topView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(topView)
let topConstraints = [topView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
topView.widthAnchor.constraint(equalToConstant: 50),
topView.heightAnchor.constraint(equalToConstant: 50),
topView.topAnchor.constraint(equalTo: scrollView.frameLayoutGuide.topAnchor, constant: 90)]
NSLayoutConstraint.activate(topConstraints)
可以看到,上下滑动,在屏幕中的位置不变。而且距离 scrollView 顶部的距离是 90,而不是 safeArea 的顶部距离是 90。
Use this layout guide when you want to create Auto Layout constraints that explicitly involve the frame rectangle of the scroll view itself, as opposed to its content rectangle.
相对于 safeArea
布局
let topConstraints = [topView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
topView.widthAnchor.constraint(equalToConstant: 50),
topView.heightAnchor.constraint(equalToConstant: 50),
topView.topAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.topAnchor, constant: 90)]
可以看到,上下滑动过程中,相对于屏幕的位置不变,只不过把位置从相对于 scrollView 的顶部,变为相对于 safeArea 的顶部。
相对于 contentLayoutGuide
布局
let topConstraints = [topView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
topView.widthAnchor.constraint(equalToConstant: 50),
topView.heightAnchor.constraint(equalToConstant: 50),
topView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 90)]
可以看到,会相对于 scrollView 的滚动区域布局,并考虑到了 safeArea。
直接相对于 scrollView
布局
let topConstraints = [topView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
topView.widthAnchor.constraint(equalToConstant: 50),
topView.heightAnchor.constraint(equalToConstant: 50),
topView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 90)]
和 contentLayoutGuide
类似
一点思考
scrollview 布局时,应该和 VC 的根 View 对齐,不应该考虑 safeArea。如果顶部和根 View 的 safeArea 的顶部对齐,那么就做不到透过顶部和底部 bar 的效果。
let constraints = [scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor)]
scrollView 有一个属性叫做 contentInsetAdjustmentBehavior
,会自动处理好 safeArea。
如果 scrollView 相对于控制器的根 View 的 safeArea 布局,结果如下。
下起雨,也要勇敢前行