为了改进较小设备的UI,当uiscrollview
contentsize.height
大于其bounds.height
时(我称之为溢出),我希望调整UI。
我的问题是:我发现视图出现在屏幕上后(在ViewDidAppear(:)
)的布局与上次出现在ViewDidLayoutSubViews()
中的布局不同(可以多次调用)。 为了确定ScrollView
是否溢出,我们需要知道ScrollView.bounds
和ScrollView.ContentSize
。 我认为这将在ViewDidLayoutSubViews()
的最后一次调用中确定。
下面举例说明我的场景。 它正在运行一个内置在xib
中的接口,其中还设置了scrollview
。 注意,没有隐藏/显示视图来干扰布局值,只需运行。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
printOverflow(type: #function)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
printOverflow(type: #function)
}
private func printOverflow(type: String) {
let isOverflowY = scrollView.contentSize.height > scrollView.bounds.height
debugPrint("[Overflow] \(type) \(isOverflowY ? "Overflow" : "Fits")")
}
// After running prints:
// "[Overflow] viewDidLayoutSubviews() Fits"
// "[Overflow] viewDidAppear(_:) Overflow"
我的问题是:为什么不能在最后一个ViewDidLayoutSubviews()
中获得子视图的最终布局?
我还尝试在ViewWillAppearch(:)
中添加了一个View.LayoutifNeed()
,实际上这激发了另一个ViewDidLayoutSubViews()
,正如您所期望的,但是Bounds
属性仍然与ViewDidAppearch(:)
中的不同(尽管实际上现在打印的是“溢出”)
来自苹果的文档(斜体是我的):
函数viewDidLayoutSubviews()
当视图控制器视图的边界改变时,视图调整其子视图的位置,然后系统调用此方法。 但是,正在调用的此方法并不表示视图的子视图的单个布局已经调整。 每个子视图负责调整自己的布局。
因此,ViewDidLayoutSubViews()
可以(也将)在自动布局完全配置子视图之前调用。 这也是我们看到ViewDidLayoutSubViews()
在加载/显示过程中被多次调用的原因。
如果您像这样对UISCROLLView
进行子类划分:
class MyScrollView: UIScrollView {
override func layoutSubviews() {
super.layoutSubviews()
printOverflow(type: #function)
}
private func printOverflow(type: String) {
let isOverflowY = contentSize.height > bounds.height
debugPrint("MyScrollView {Content Size: \(contentSize.height) Bounds Height: \(bounds.height)} [Overflow] \(type) \(isOverflowY ? "Overflow" : "Fits")")
}
}
你会发现你得到了正确的高度。
到底是为了“改善更小设备的UI”而尝试做些什么呢? 可能还有其他(更好的?) 选项。。。