How to get real size UIView with autolayout
Asked Answered
D

8

41

I'm a new developer iOS.

I use auto-layout.

I have a problem. I can not get real size of UIView after constraints.

Example, when I want get size of UIView with constraint

self.container.frame.size.height

It alway return 550 for all device size. But I can see it have difference size when I run it on difference device.

Thanks

Dulse answered 26/12, 2014 at 5:45 Comment(0)
B
17

The simplest solution is to just run that code in -viewDidAppear: (after autolayout has been run).

Beera answered 26/12, 2014 at 5:48 Comment(2)
Thanks. But how to do if i want get real size in viewDidLoad. Have you got any solution?Dulse
@Dulse See Allen's solution. This will force auto-layout to be run immediately. You really should avoid doing that sort of thing especially more than once.Beera
N
55

Before your "getting real size code", insert the following code:

[view setNeedsLayout];
[view layoutIfNeeded];
Noway answered 7/4, 2015 at 3:52 Comment(2)
IMHO no need to call both [view setNeedsLayout] and [view layoutIfNeeded], only the latter was enough for me in viewWillLayoutSubviewsSwinish
Swift 4 Answer: Just what @Noway said actually, just insert view.setNeedsLayout() view.layoutIfNeeded() above the code that you are trying to get the true size of things you are using. Because viewDidAppear code applies after the animations which may look ugly for some people.Tega
A
22

Since everybody assumes the access is done via a UIViewController and not inside a UIView subclass, the answers don't prove really useful. The correct way to get the correct size of a UIView subclass is in layoutSubviews.

Arin answered 6/7, 2015 at 14:28 Comment(1)
I calculate the size in layoutSubviews. But it only works if I call layoutIfNeeded just before the height calculation. calling self.setNeedsLayout, also works. I wounder which one is best?Jalap
B
17

The simplest solution is to just run that code in -viewDidAppear: (after autolayout has been run).

Beera answered 26/12, 2014 at 5:48 Comment(2)
Thanks. But how to do if i want get real size in viewDidLoad. Have you got any solution?Dulse
@Dulse See Allen's solution. This will force auto-layout to be run immediately. You really should avoid doing that sort of thing especially more than once.Beera
B
15

Seems like - (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize; is what you are looking for:

Return Value
The size of the view that satisfies the constraints it holds.

Discussion
Determines the best size of the view considering all constraints it holds and those of its subviews.

https://developer.apple.com/documentation/uikit/uiview/1622624-systemlayoutsizefittingsize?language=objc

Beneficiary answered 2/11, 2017 at 17:36 Comment(0)
F
13

You could just use the UIView method intrinsicContentSize

enter image description here

which you can read about https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instm/UIView/intrinsicContentSize

Fathometer answered 26/12, 2014 at 13:37 Comment(2)
This should be the correct answer. If you are doing auto layout programmatically and not explicitly setting frames, this is the proper way to get the height/weight based on content.Cyan
@Cyan intrinsicContentSize ignores (as the name suggests, and is also mentioned in the screenshot above) all constraints affecting the view. For example, a label's intrinsic content size is simply the frame it would take to display the label's text. But if your label has a "width <= 200" constraint, that would be ignored. However, OP explicitly asked for the view's size "after constraints".Zarate
R
9

This is awesome.

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

dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"View frame: %@", NSStringFromCGRect(view.frame));
    })
Rowe answered 29/12, 2015 at 13:6 Comment(2)
Thank you for this idea. Nothing is strange here: you are asking this code to be called after getting back to the main dispatch queue. This will happen after auto-layout took place. Very useful indeed!Conformal
Thanks. Not strange as Sam says. Also a better solution than subclass views just for this.Ursine
C
3

[view layoutIfNeed] save me.

Use this method to force the layout of subviews before drawing. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root.

After invoke this method, I can get actual size of custom view in xib. Thanks a lot to @Allen and the author.

Cara answered 6/10, 2015 at 3:3 Comment(1)
This is what I needed, my view was not getting the correct size in 'viewDidLayoutSubviews' so I called layoutIfNeeded in the call and everything is working fineColunga
M
2

The best moment is during the viewDidLayoutSubviews because it happens before the viewDidAppearso you still are able to do some modifications before the view is displayed.

Mishamishaan answered 26/12, 2014 at 13:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.