0

I'm still a little fuzzy on the relationship between a view's alignment rectangle property, and the same view's frame property.

I know as developers we can't directly in code change the alignment rectangle property, and that we can manipulate it through constraints in the interface builder. I also know (or think I know) that the alignment rectangle property has many more values than the CGRect, i.e. Top, Left, Right, Bottom, Leading, Trailing, Baseline, etc...

What I don't understand is how these two function together in a view.

When you're looking at a view that has constraints on it, say a UILabel, is the original CGRect frame property even being used anymore? Or has the Alignment rectangle property taken over for that view (to make it responsive and calculate width/height/origin location at runtime)?

The book suggests to rarely use a view where its frame is a simple CGRect object with an x and y origin, and a fixed width/height, and instead to use constraints which have to do with the view's alignment rectangle property.

So basically.. I have you have a label that you have put constraints on and the frame is now 'responsive', is that frame property of the view even being used still? And if so, how and why?

Thanks

user7024499
  • 951
  • 1
  • 10
  • 24

1 Answers1

3

The view's frame is lower-level than Auto Layout. The frame stores the rectangle that the view occupies; that's it. When drawing views, dealing with touches, etc., UIKit uses the view's frame. The frame is the current position and size of the view; nothing else is.

Auto Layout sets the view's frame. If you use Auto Layout to specify constraints for a view, Auto Layout will calculate the frame the view should have base on and set that frame into it's frame property when it runs.

Auto Layout is run by layoutSubviews() of UIView, which runs when the view is added as a subview or its size is changed. You can set the frame yourself, but it will be reset by Auto Layout the next time layoutSubviews() runs.

Community
  • 1
  • 1
NobodyNada
  • 7,529
  • 6
  • 44
  • 51
  • Thank you so much for the clear understanding. So if you do not set any constraints on a subview for instance a button, then that view's layoutSubviews() will not be invoked, therefore the original, set-in-stone CGRect frame will render for the view? – user7024499 Dec 06 '16 at 21:29
  • @user7024499 The `layoutSubviews` will still be invoked; I'm pretty sure it just won't do anything. Remember, `layoutSubviews` layouts the **subviews**; so if you want to layout a view, you have to ask it's superview to `layoutSubviews`. – NobodyNada Dec 06 '16 at 21:31
  • Oh okay so whenever a view detects that a subview has been added to it, it runs layoutSubviews()? – user7024499 Dec 07 '16 at 23:50
  • @user7024499 Yes; according to [When is layoutSubviews called?](http://stackoverflow.com/a/5330162/3476191), "addSubview: causes layoutSubviews to be called on the view being added, the view it’s being added to (target view), and all the subviews of the target." – NobodyNada Dec 08 '16 at 00:05