移动viewDidLayoutSubviews()
时,我的ViewController的UISlider
方法被重复调用。 (我需要它被调用一次,所以我可以弄清楚子视图的大小 - viewDidLoad()
在过程中过早 - 但是当我拖动UISlider
时,它被无限地称为广告。)
任何想法都将不胜感激!
答案 0 :(得分:1)
UISlider
使用拇指和轨道部分的子视图绘制自己。这是一个简单的测试应用程序的视图层次结构:
<UIWindow: 0x7d26cf90; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x7d2609a0>; layer = <UIWindowLayer: 0x7d25f0c0>>
| <UIView: 0x7d27d530; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x7d27cec0>>
| | <UISlider: 0x7d27d700; frame = (14 225; 292 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7d27d960>; value: 0.513699>
| | | <UIView: 0x7b755a50; frame = (150 15; 140 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7b7559d0>>
| | | | <UIImageView: 0x7b7551d0; frame = (-148 0; 288 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7b755410>>
| | | <UIImageView: 0x7b755640; frame = (2 15; 148 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7b755720>>
| | | <UIImageView: 0x7d5c3450; frame = (134 0; 31 31); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7d5c4750>>
| | | | <UIImageView: 0x7d5c44a0; frame = (-13 -6.5; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7d5c6c20>>
| | <_UILayoutGuide: 0x7d27daa0; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x7d27ccf0>>
| | <_UILayoutGuide: 0x7d27e020; frame = (0 480; 0 0); hidden = YES; layer = <CALayer: 0x7d27e0f0>>
请注意,UISlider
总共有五个后代视图。这是一个您不应该依赖的实施细节,但它有助于了解正在发生的事情。
当滑块需要更改其值时,它会将新值存储在实例变量中并设置自己的needsLayout
标志。最终,运行循环到达布局阶段,并且更新视图层次结构布局,从窗口开始并沿着层次结构向下移动。当它到达滑块时,滑块会更新其子视图&#39;帧根据其值和其他实例变量。
如果您需要知道子视图的大小,可能需要自己调用layoutIfNeeded
,然后立即获取子视图的大小,以便布局在您的控制下进行。
答案 1 :(得分:0)
由于您提及viewDidLoad
为时尚早,您可以在viewWillAppear:
或viewDidAppear:
进行计算吗?
viewDidLayoutSubviews
。您无法依赖或更改此被调用的频率(例如,当状态栏更改高度时会调用它。)