iOS AutoLayout - get frame size width

感情迁移 提交于 2020-01-08 13:56:08

问题


I am developing using iOS 6 auto layout

I would like to log a message displaying the frame width of the view.

I can see the textView on the screen.

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

回答1:


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).

Edit: this answer points out why the scenario in the question doesn't work. @dreamzor's answer points out where to place your code in order to solve it.




回答2:


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

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.

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




回答3:


Solution

  • Place that code in viewDidAppear

Reason

  • viewDidLoad happens before autolayout is completed. So the position is not yet set by autolayout that was specified in xib
  • viewDidAppear happens after autolayout is completed.



回答4:


Include in your viewDidLoad()

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

Before accessing yourview.frame.size.width




回答5:


Actually I managed to force the layout update before my code within the 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




回答6:


This is really strange feature. But I found:

If you want to get frame without using layoutsubviews method, Use this one:

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

This is really strange!!!




回答7:


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.

viewDidLayoutSubviews should be 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.

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.

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.

And no, we shouldn't have to do this, but until Apple gives us some more reliable callbacks, we're all stuck with it.




回答8:


iOS AutoLayout - get frame size width

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



回答9:


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


来源:https://stackoverflow.com/questions/12527191/ios-autolayout-get-frame-size-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!