How to Get a View's Current Width and Height When Using Autolayout Constraints

How can I get a view's current width and height when using autolayout constraints?

The answer is [view layoutIfNeeded].

Here's why:

You still get the view's current width and height by inspecting view.bounds.size.width and view.bounds.size.height (or the frame, which is equivalent unless you're playing with the view.transform).

If what you want is the width and height implied by your existing constraints, the answer is not to inspect the constraints manually, since that would require you to re-implement the entire constraint-solving logic of the auto layout system in order to interpret those constraints. Instead, what you should do is just ask auto layout to update that layout, so that it solves the constraints and updates the value of view.bounds with the correct solution, and then you inspect the view.bounds.

How do you ask auto layout to update the layout? Call [view setNeedsLayout] if you want auto layout to update the layout on the next turn of the run loop.

However, if you want it to update the layout immediately, so you can immediately access the new bounds value later within your current function, or at another point before the turn of the run loop, then you need to call [view setNeedsLayout] and [view layoutIfNeeded].

You asked a second question: "how can I change a height/width constraint if I don't have a reference to it directly?".

If you create the constraint in IB, the best solution is to create an IBOutlet in your view controller or your view so you do have a direct reference to it. If you created the constraint in code, then you should hold onto a reference in an internal weak property at the time when you created it. If someone else created the constraint, then you need to find it by examining the examining the view.constraints property on the view, and possibly the entire view hierarchy, and implementing logic which finds the crucial NSLayoutConstraint. This is probably the wrong way to go, since it also effectively requires you to determine which particular constraint determined the bounds size, when there's not guaranteed to be a simple answer to that question. The final bounds value could be the solution to a very complicated system of multiple constraints, with multiple priorities, etc., so that no single constraint is the "cause" of the final value.

Swift get actual view size after setting constraints

You have a couple of options; based on your use case:

  1. Get your frame by using:

    DispatchQueue.main.async {
    //print(self.view.frame)
    }
  2. get your updated frame values in viewDidAppear

  3. get your updated frame values in viewDidLayoutSubviews. But be careful this is called multiple times.

Programmatically retrieve the width and height of a UIView using Auto Layout and NSLayoutConstraints?

You have a few options:

You can force the layout engine to size the views immediately by calling setNeedsLayout and then call layoutIfNeeded. This is not recommended because it's inefficient and any manual frames required for layout might not have been set yet. You can read more about this approach on my answer to this question.

You can also wait until the subviews have been updated in the view controller:

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
println("stageView.frame = \(stageView.frame)")
}

If you want to know within a UIView subclass (or more often, a UITableViewCell subclass, you can check after layoutSubviews has run:

override func layoutSubviews() {
super.layoutSubviews()
println("self.frame = \(self.frame)")
}

Xcode: Setting width and height in Utilities / Size / View versus as a constraint

First of all welcome to iOS development :)

The answer is: In case 2 you are using Autolayout and in case 1 you are not.

Autolayout is really important and you should definitely always use it. The constraints allow you to create "rules" that tell the app how to adjust the UI to different screen sizes. In your case the button might have the same size for all screens, but without setting the constraints the size might change nevertheless depending on the layout of the constraints of other UI Components.

I recommend reading a tutorial about Autolayout. It is easy to learn and hard to master I would say...

How to change the height of the view based on width

Use concept of aspect ratio with AutoLayout to update your view with respect to height & width. Use multiplier to update aspect ratio. Here are snap of aspect ration assignment and how to update it's multiplier

Sample Image
Sample Image

Logic of Multiplier:

1:1 = Height and width of your image will remain same

2:1 = Your width or height is 2x with respect to each other and create a rectangle. Here Height will be 2x or width will be 2x, it depends upon first item and second item in constraint.

Logic of Priority:
Priority assigns, priority to specific constraint when it conflicts with another constraint of same view. e.g. if you have set a view with 1:1 aspect ratio, with 100 height & 100 width and centred in Main View. Now you also assign Left (margin)/Leading constraint as fix value like 200. In that case for different size of screen width, Centred alignment and/or Leading alignment and/or aspect ration will conflict each other. At this point you need to update priority between 0-1000, according to your requirement for adjustment of design.

Share me your design, I will give your exact logic, how to use this concept

iOS AutoLayout - get frame size width

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.



Related Topics



Leave a reply



Submit