我有一种情况,我正在使用UIScrollView来帮助使用较小手机的用户查看窗口内的全文。我想要显示一个图像图标,如果他们需要滚动(只是为了让他们知道窗口内有更多内容)但是我在使用Swift查找scrollview的高度时遇到了问题。
这是我的对象的层次结构
基本上,这4个标签适合4.7“iPhone而不是4”iPhone。我尝试设置一些逻辑来检查UIScrollView内容是否大于窗口,但它似乎没有工作。我一直认为高度为零。
我正在使用scrollHeight = scrollView.contentSize.height
并尝试将其置于viewDidLoad()
,viewWillAppear()
和viewDidLayoutSubviews()
内,但每次最终都为0。
contentSize
我应该用它来检查身高吗?
答案 0 :(得分:8)
<强> TL; DR; 强>
作为一般指南,自动布局无法在调用viewDidLoad
时完成视图的大小(在viewDidLayoutSubviews
内也不正确)。要在查询bounds
或frame
之前确保所有观看次数及其子视图的尺寸正确,请执行以下操作:
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
print(self.someSubview.frame) // gives correct frame
<强>解释强>
有点违反直觉,将代码放在viewDidLayoutSubviews
中并不意味着所有子视图都通过自动布局给出了正确的大小。引用the docs for this method:
但是,调用此方法并不表示已调整视图子视图的各个布局。
这意味着:在viewDidLayoutSubviews
内,只有第一层次的子视图具有正确的大小(即子视图,但不是#34;孙视图和#34;)。
这是我创建的示例布局(红色视图是子视图,蓝色视图是孙视图)。
关于这个例子的一些要点:
请注意,在Interface Builder中,子视图的原始宽度(红色)为240磅,孙子视图的原始宽度(蓝色)为200磅。
以下是代码:
class ViewController: UIViewController {
@IBOutlet weak var childView: UIView!
@IBOutlet weak var grandchildView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
print("child ", #function, childView.frame.size.width)
print("grandchild", #function, grandchildView.frame.size.width)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("child ", #function, childView.frame.size.width)
print("grandchild", #function, grandchildView.frame.size.width)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("child ", #function, childView.frame.size.width)
print("grandchild", #function, grandchildView.frame.size.width)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("child ", #function, childView.frame.size.width)
print("grandchild", #function, grandchildView.frame.size.width)
}
}
这是输出:
child viewDidLoad() 240.0
grandchild viewDidLoad() 200.0
child viewWillAppear 240.0
grandchild viewWillAppear 200.0
child viewDidLayoutSubviews() 271.0 // `child` has it's final width now
grandchild viewDidLayoutSubviews() 200.0 // `grandchild` still has it's original width!
// By now, in MOST cases, all views will have their correct sizes.
child viewDidAppear 271.0
grandchild viewDidAppear 231.0
您可以从此输出中看到,viewDidLayoutSubviews
不保证通过View Controller的主视图的直接子视图的任何内容都具有正确的大小。
注意:通常在调用viewDidAppear
时,视图的大小正确,但我说这无法保证