iOS AutoLayout - 获取帧大小宽度

时间:2012-09-21 08:49:07

标签: ios nslog autolayout

我正在使用iOS 6自动布局

进行开发

我想记录一条显示视图框宽的消息。

我可以在屏幕上看到textView。

但我的宽度和高度为零,我错过了什么吗?

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

10 个答案:

答案 0 :(得分:153)

实际上,上述答案并不完全正确。我跟着他们,一次又一次地得到了零。

诀窍是将依赖于帧的代码放到viewDidLayoutSubviews方法中,

  

通知视图控制器其视图刚刚布置了其子视图。

不要忘记这个方法被多次调用,并且不是ViewController生命周期的一部分,所以在使用它时要小心。

希望对某人有所帮助。

只是想补充一点,对于我的没有横向模式的程序而言,不使用自动布局更加简单......我试过了,虽然= D

答案 1 :(得分:56)

我认为自动布局没有时间在你调用它时布局你的视图。调用时viewDidLoad时没有发生自动布局,因为它在加载视图后立即被调用,并且仅在此之后将视图放置到视图控制器的视图层次结构中并最终布局(在视图中) layoutSubviews方法)。

编辑:这个答案指出了为什么问题中的场景不起作用。 @dreamzor's answer指出了代码放置的位置,以便解决问题。

答案 2 :(得分:29)

<强>解决方案

  • 将该代码放入viewDidAppear

<强>原因

  • viewDidLoad在自动布局完成之前发生。因此,该位置尚未通过xib
  • 中指定的autolayout设置 自动布局完成后,
  • viewDidAppear发生。

答案 3 :(得分:29)

包含在viewDidLoad()

self.view.setNeedsLayout()
self.view.layoutIfNeeded()

访问yourview.frame.size.width

之前

答案 4 :(得分:13)

实际上我在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()
    }

更新:这似乎不再适用

答案 5 :(得分:10)

这是非常奇怪的功能。但我发现:

如果您想在不使用layoutsubviews方法的情况下获取帧,请使用此选项:

dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"View frame: %@", NSStringFromCGRect(view.frame));
    });

这真奇怪!!!

答案 6 :(得分:7)

除了viewDidLoad之外,上述答案都没有完全适用于我,但是副作用是在视图动画显示之前不显示我想要的内容,看起来很差。

viewDidLayoutSubviews 应该是运行依赖于自动布局完成的代码的正确位置,但正如其他人指出的那样,它在最近的iOS版本中被多次调用,你可以&# 39;知道哪个是最后的电话。

所以我用一个小黑客解决了这个问题。在我的故事板中,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...

    }
}

这样做的好处是不依赖于硬编码的数字,因此它可以适用于所有iPhone外形尺寸。当然,它可能不是所有情况下或所有设备上的灵丹妙药,但可能有许多巧妙的方法来进行相对大小的类似检查。

不,我们不应该这样做,但在Apple给我们一些更可靠的回调之前,我们都会坚持下去。

答案 7 :(得分:2)

  

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];
    }

答案 8 :(得分:1)

您只能在第一次布局通过后找到尺寸。或者只要在获得实际宽度后再调用以下方法。

[yourView layoutIfNeeded];

答案 9 :(得分:0)

我同意“ user1046037”的解决方案

如果同时使用atuoLayout指南和代码,则最好将框架(或NSlayoutConstraints)编程放入“ ViewDidAppear ”中,尤其是在为多个设备设计UI时

根据我的测试,iOS14会在“ ViewDidLoad ”之前从屏幕(默认iPhone 11 Pro Max)获取屏幕自动布局,并在“ ViewDidAppear ”中进行更新。

对于不熟悉视图周期的人,其“从情节提要中加载视图”->“ ViewDidLoad ”->“ ViewWillAppear ”->“ ViewDidAppear ”。