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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:17:47  来源:igfitidea点击:

iOS AutoLayout - get frame size width

iosnslogautolayout

提问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 viewDidLoadis 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 layoutSubviewsmethod).

我认为汽车布局一直没有被你调用这个时间来布置你的意见的时间。自动布局在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 viewDidLayoutSubviewsmethod, 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

原因

  • viewDidLoadhappens before autolayout is completed. So the position is not yet set by autolayout that was specified in xib
  • viewDidAppearhappens 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 viewDidLoadbut that has the side effect of not displaying what I want until after the view has animated in, which looks poor.

上述答案都没有完全适合我,viewDidLoad但它的副作用是在视图动画进入之前不显示我想要的内容,这看起来很糟糕。

viewDidLayoutSubviewsshouldbe 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, mySubviewshould be smaller than its containing self.view. But when viewDidLayoutSubviewsis first called, mySubviewstill has a width of 600, whereas self.viewseems 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 mySubviewis smaller than self.viewI 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];
    }