iOS AutoLayout - 获取框架大小宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12527191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS AutoLayout - get frame size width
提问by user1046037
I am developing using iOS 6 auto layout
我正在使用 iOS 6 自动布局进行开发
I would like to log a message displaying the frame width of the view.
我想记录一条显示视图框架宽度的消息。
I can see the textView on the screen.
我可以在屏幕上看到 textView。
But I get the width and height as zero, am I missing something ?
但是我得到的宽度和高度为零,我错过了什么吗?
NSLog(@"textView = %p", self.textView);
NSLog(@"height = %f", self.textView.frame.size.height);
NSLog(@"width = %f", self.textView.frame.size.width);
textView = 0x882de00
height = 0.000000
width = 0.000000
采纳答案by Jesper
I think auto layout hasn't had the time to layout your views by the time you call this. Auto layout hasn't happened by the time viewDidLoad
is called, because it's called just after the views are loaded and it's only after that that the views are placed into the view controller's view hierarchy and eventually laid out (in the view's layoutSubviews
method).
我认为汽车布局一直没有被你调用这个时间来布置你的意见的时间。自动布局在viewDidLoad
调用时尚未发生,因为它在视图加载后才被调用,并且仅在此之后将视图放置到视图控制器的视图层次结构中并最终布局(在视图的layoutSubviews
方法中)。
Edit: this answer points out why the scenario in the question doesn't work. @dreamzor's answerpoints out where to place your code in order to solve it.
编辑:这个答案指出了为什么问题中的场景不起作用。@dreamzor 的回答指出了在哪里放置代码以解决它。
回答by dreamzor
Actually, above answers are not quite right. I followed them and got zeros again and again.
其实上面的回答都不太对。我跟着他们,一次又一次地得到零。
The trick is to place your frame-dependent code to the viewDidLayoutSubviews
method, which
诀窍是将依赖于框架的代码放置到viewDidLayoutSubviews
方法中,其中
Notifies the view controller that its view just laid out its subviews.
通知视图控制器它的视图刚刚布局了它的子视图。
Do not forget that this method is called multiple times and is not the part of ViewController's life cycle, so be careful while using this.
不要忘记这个方法会被多次调用,并且不是 ViewController 生命周期的一部分,所以在使用它时要小心。
Hope it will be helpful to someone.
希望它会对某人有所帮助。
Just wanted to add, that for my program without landscape mode NOT using Auto Layout is way much simplier... I tried, though =D
只是想补充一点,对于我的没有横向模式的程序,不使用自动布局要简单得多......我试过了,虽然=D
回答by diegosantiviago
Include in your viewDidLoad()
包含在您的 viewDidLoad() 中
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
Before accessing yourview.frame.size.width
在访问 yourview.frame.size.width 之前
回答by user1046037
Solution
解决方案
- Place that code in
viewDidAppear
- 将该代码放入
viewDidAppear
Reason
原因
viewDidLoad
happens before autolayout is completed. So the position is not yet set by autolayout that was specified in xibviewDidAppear
happens after autolayout is completed.
viewDidLoad
在自动布局完成之前发生。因此,位置尚未由 xib 中指定的自动布局设置viewDidAppear
自动布局完成后发生。
回答by Francescu
Actually I managed to forcethe layout update before my code within the viewDidLoad
:
实际上,我设法在我的代码之前强制进行布局更新viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
println("bounds before \(self.previewContainer.bounds)");
//on iPhone 6 plus -> prints bounds before (0.0,0.0,320.0,320.0)
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
println("bounds after \(self.previewContainer.bounds)");
//on iPhone 6 plus -> prints bounds after (0.0,0.0,414.0,414.0)
//Size dependent code works here
self.create()
}
UPDATE: This doesn't seem to work anymore
更新:这似乎不再起作用
回答by SamSol
This is really strange feature. But I found:
这真是一个奇怪的功能。但我发现:
If you want to get frame without using layoutsubviews method, Use this one:
如果您想在不使用 layoutsubviews 方法的情况下获取框架,请使用以下方法:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"View frame: %@", NSStringFromCGRect(view.frame));
});
This is really strange!!!
这真的很奇怪!!!
回答by Echelon
None of the above answers worked completely for me, except viewDidLoad
but that has the side effect of not displaying what I want until after the view has animated in, which looks poor.
上述答案都没有完全适合我,viewDidLoad
但它的副作用是在视图动画进入之前不显示我想要的内容,这看起来很糟糕。
viewDidLayoutSubviews
shouldbe the correct place to run code that relies on the autolayout being complete, but as others have pointed out it is called multiple times in recent iOS versions and you can't know which is the final call.
viewDidLayoutSubviews
应该是运行依赖于自动布局完成的代码的正确位置,但正如其他人指出的那样,它在最近的 iOS 版本中被多次调用,您不知道哪个是最终调用。
So I resolved this with a small hack. In my storyboard, mySubview
should be smaller than its containing self.view
. But when viewDidLayoutSubviews
is first called, mySubview
still has a width of 600, whereas self.view
seems to be set correctly (this is an iPhone project). So all I have to do is monitor subsequent calls and check the relative widths. Once mySubview
is smaller than self.view
I can be sure it has been laid out correctly.
所以我用一个小技巧解决了这个问题。在我的故事板中,mySubview
应该小于其包含的self.view
. 但是当viewDidLayoutSubviews
第一次调用时,mySubview
宽度仍然为 600,而self.view
似乎设置正确(这是一个 iPhone 项目)。所以我所要做的就是监视后续调用并检查相对宽度。一次mySubview
小于self.view
我可以确定它已正确布局。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if self.mySubview.bounds.size.width < self.view.bounds.size.width {
// mySubview's width became less than the view's width, so it is
// safe to assume it is now laid out correctly...
}
}
This has the advantage of not relying on hard-coded numbers, so it can work on all iPhone form factors, for example. Of course it may not be a panacea in all cases or on all devices, but there are probably many ingenious ways to do similar checks of relative sizes.
这具有不依赖于硬编码数字的优点,因此它可以适用于所有 iPhone 外形尺寸,例如。当然,它可能不是所有情况下或所有设备上的灵丹妙药,但可能有许多巧妙的方法可以对相对大小进行类似的检查。
And no, we shouldn't have to do this, but until Apple gives us some more reliable callbacks, we're all stuck with it.
不,我们不应该这样做,但是在 Apple 给我们一些更可靠的回调之前,我们都会坚持下去。
回答by Bhavesh Patel
You can only find out the size after the first layout pass. Or Just call below method then after you got actual width of you view.
您只能在第一次布局通过后找出尺寸。或者,在获得视图的实际宽度后,只需调用下面的方法。
[yourView layoutIfNeeded];
回答by Ravi Kumar
iOS AutoLayout - get frame size width
iOS AutoLayout - 获取框架大小宽度
-(void) layoutSubviews{
[self layoutIfNeeded];
//right you code to set frame its will work to get frame and set frame.
CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0.0f, bkView.frame.size.height - 1, bkView.frame.size.width, 1.0f);
bottomBorder.backgroundColor = [UIColor blackColor].CGColor;
[bkView.layer addSublayer:bottomBorder];
}