In one of the WWDC 2012 videos, Auto Layout By Example, they demo an OS X app using Autolayout, and at about 7 or 8 minutes in, he shows how for a single view, you can uncheck a box in the Attributes Inspector, and the box is called something like "Translates Autoresizing Mask Into Constraints". Now, I'm well aware of the code equivalent of this box, the translatesAutoresizingMaskIntoConstraints boolean, but I can't seem to find this checkbox anywhere in either iOS or OS X projects. My project uses Autolayout. I really would like this checkbox, because one of things I'm struggling with in learning Autolayout (and converting a springs/struts app to AL) is the million constraints Xcode has generated for each view, and how to clean them up and sensibly override some/all in code. What I'd like in order to do this conversion one view at a time is to turn off those auto-generated constraints.
Why can't I see this checkbox? I'm using Xcode 4.6.
That checkbox is available in Interface Builder (IB), but only if you are developing Cocoa projects targeted for OS X. For iOS, it's not available at present. You can only set it programmatically.
Auto Layout on iOS from my understanding - and others feel free to pitch in here - is not a full implementation of what is available on OS X.
To be honest, given what you say afterwards, this checkbox is probably something you don't need to worry about. I think it is important in upgrading OS X projects to Auto Layout, but generally for iOS it's unlikely you'll be mixing one and the other. I.e., you either checkbox your Xib in the File Inspector to "Use Autolayout" or you don't.
That said, there is one use case where you may need to mess with that flag. That's if you want to create a standalone Xib file for a view, and then load that programmatically using loadNibNamed. When doing that, by default old style Auto Resizing constraints are converted into new style Auto Layout constraints. Typically I want to add my own so I set that flag to zap 'em.
myView.translatesAutoresizingMaskIntoConstraints = NO
Anyway that's another story.
Here's the link for more info, although you've no doubt had a look at it already:
Adopting Auto Layout
One thing I'd say is that if you're struggling with Auto Layout in the beginning - and you wouldn't be human if you weren't, we all have been - then I'd stick with Interface Builder and think about the golden rules. The most important one for me is that it hates ambiguity. It's like a vacuum in nature. Before you can delete the constraint that you don't want, you have to add the one that you do want then zap the old one.
The other mistake that I made was mixing Auto Layout and frames. So I'd do some code that checked the frame width then apply that to the constraints. Bad mistake. That really ends in tears. When you get into Auto Layout it's essential to really forget about doing anything with CGRect, frame, etc.
Stick with it though. Start with some simple views in IB and experiment. There is method to the madness, really.
One more link also worth looking at is:
10 Things You Need To Know About Cocoa Autolayout
Related
In Xcode, when using the autoresizing option for any type of object, things seem to stay where they're supposed to be while maintaining a proportional size to the scene. I generally just select the inside arrows in the autoresizing box and everything maintains adequate sizes and proportions. However, I've seen multiple times on tutorials, blogs and videos that using constraints is "the right way". Why would the use of constraints be better than autoresizing when autoresizing seems to work perfectly? Would any problem surge when using autoresizing if I work only on iPhone in portrait mode?
Well there are a two reasons I think. The first is probably the most accurate, but might leave you feeling weird after. Because Apple is pushing it. Usually when apple is backing a new tool in their api, its wise to follow because they will drop support for old things you get used to like Autoresizing. Kinda sucks I know.
The second (better) reason that Autolayout will let you write view components that you can reuse between many different screen sizes. Yea Autoresizing helps, but Autolayout gives you more control when the screen size makes a large change like from iPhone to iPad. I've written views that live in all my iphone/ipad/apple tv apps.
An important reason is to allow views showing text, such as labels or buttons with titles, to adapt to the text content and font.
The text content should change due to internationalization/localization.
The font can change if Apple changes the system font or if the user asks for larger text to make reading easier.
With proper application of auto layout, your layout can adapt to such changes and still look good. Without auto layout, you would need to manually alter the layout to accommodate such changes.
I'm trying try hide table view and move a button up the screen, which is different to my autolayout setup. Basically, I have a free version of my app where I hide things, then if they purchase I need to set the constraints back to those in interface builder.
I have a similar question open, but I think I'm fundamentally flawed in my approach.... (I've taken the advice of something who provided and answer, asking this separate question).
ObjC, revert to interface builder autolayout constraints, after adding / removing programmatically?
I can move things up fine, which modifies my interface builder constraints.
But, when the user clicks upgrade, I cannot then set the modify they again / constraints back.
No matter what I do, use visual format language at runtime, or use NSLayoutConstraint constraintWithItem outlets to copy and then modify my constraints it doesn't change. I've tried removing constraint outlets, copying those I stored at viewdidload and remove vfl constraints, exact copies of those which I added for my free version.
I was getting some vfl warnings, until I added priorities.
Is there somewhat I can dump out the vfl for everything and try and figure out the problem or can something suggest the why the approaches I have tried have failed?
Instead of attempting to replace and restore constraints at runtime, consider setting up all the constraints you will need in Interface Builder, with references to those which are state-dependent. Then, when state changes according to your own logic, activate the state-appropriate constraint(s) and deactivate the inappropriate ones. NSLayoutConstraint has an active property, which determines whether it is used for laying out its view.
I have looked at umpteen tutorials, google posts and questions on SO but am still struggling with best way to layout a page for an iPhone app.
Part of the problem is many of the tutorials and questions are old and discuss ways that may have been optimal at some time in past.
Now, in May 2015, what is best-simplest way to have things like textfields and images layout so they display properly in common iPhones i.e. iPhone 4, 5, 6 and 6Plus?
Is it necessary to use constraints? I've gone down this road but found it very labor intensive?
Can you use blue lines as recommend in Stanford 193P tutorial? Or is there any rule of thumb way to layout a picture or a text box so that it looks good in multiple formats i.e. some number of points or using blue lines.
Storyboard in Xcode 6.0 is now 600x600 from what I can tell so a lot of times what you lay out looks horrible in the simulator. But the simulator is not an actual iPhone.
Thanks for any suggestions on right way to do this.
My answer is AutoLayout,in other words Create constraints
You can change storyboard to device as you like by click here.
You can use blue line as reference then let XCode auto create. But in this way,you are not always get right layout
Also,you can create layout by here
And you can create layout by Control + drag
By create layout,it is easy to place you views
You essentially have two choices; constraints or frame math. Both have their benefits and detriments.
The benefit of layout constraints is that you can figure out universal relationships between subviews and their superview. (e.g. It's always 20 points from leading and trailing edges or it's always dead center x and y) Once you do that, you only need to write layout code once and it will work across all device screen sizes. Also, if you ever plan to support iPad or rotation on iPhone, the work it will take to support that functionality is minimal. Another huge benefit is that if a view's frame changes, it will take care of resizing and laying out all of its subviews for you so you can modify the size of a container for example and not have to reset all of it's children's frames manually.
Constraints are "more modern" than frame math and definitely Apple's preferred method.
The issue with constraints is that the code is more verbose. Views also depend on their superviews to lay themselves out. If everything is done correctly it works great. But if you make a mistake adding constraints to one view it has the potential to trash everything else that depends on it. Once you get everything figured out it does exactly what it advertises. But getting to that point can be, in my opinion, more complicated than setting frames explicitly since there are more moving parts.
Frame math still has it's place sometimes. It has the benefit of being fast and relatively concise. Back when iPhones all had the same sized displays it worked great and if you are laying out in a view with a guaranteed rect there's no reason to need to avoid setting frames.
The problem with frames is that you are expected to support all the devices that run iOS 8. If you are laying out with frames that means you could have to write 5 different sets of layout code to support 4s, 5, 6, 6+, and iPad and 5 more sets if you want them all to rotate. This isn't always tenable.
In the end it comes down whether or not your containing view has a guaranteed height and width. If the answer is yes (like laying out inside of a collection view cell with a static width and height for example), I would have no problem leaning towards frames. If not, auto layout is the way to go.
I've been having such a hard time trying to figure out how this thing works. It's so random and I have no idea what else to try. I've looked up multiple articles on this issue and everyone just says change the scale. Changed the scale does not help, it's got nothing to do with what's happening here. I'm not sure if this is related to the bottom of Xcode where you can change the dimensions (Any vs Any / Any vs Regular Height, etc...) I've asked my mobile development teacher at school as well and he couldn't figure it out either. Any help would be greatly appreciated!!
Picture below:
http://tinypic.com/r/281fw5w/8
Your problem is not scaling. What you need to look at is auto layout and constraints.
You can use the icons in the lower right edge of the interface builder to get at them or control drag from a view controller (like a button, label, etc.) to the containing view (or any other view controller for that matter.) Usually, the main view window itself. When you release you can now add constraints to "attach" the element to that other element relatively. For instance, you could attach the things on the left to the left side and the things on the right to the right side. Now, regardless of the dimension of the actual device screen, those elements will appear in those locations relative to the device screen.
The problem is that the position of elements from your perspective is right for the canvas you see in the Interface builder, but once the app is run, the real canvas has different dimensions.
To manage the position, size and other attributes of UI elements, there is a system called AutoLayout.
It is quite ingenious because it is similar to natural language.
For example "I want this element to be in the middle of the screen."
or
"I want this element to be 20 pixels from the left corner and 57 pixels from the element that is above this element."
By combining these rules you basically create a set of layout constraints, that are applied in runtime to the view hierarchy and view are laid out properly.
Autolayout allows for very sophisticated layouts.
Another aspect you need to take into account that you might want your app to look well in all form factors from 3.5 inch iPhone up to iPad air.
Since these devices differ considerably in size, Apple introduced an abstraction called Size Class.
Size Class is an abstraction on top of concrete size. Concrete iOS devices have vey concrete dimensions. But in natural language you often say it's big ,or small ,or normal. And this the level of abstraction size classes use.
For each size class you can have a particular set of auto layout constraints.
So by combining AutoLayout and SizeClasses, Apple solved the problem oh how to have one application but one that can still accommodate specific form factors and can adjust its layout to them.
In Xcode6, all storyboards/xib files have autolayout & sizeclasses enabled by default. Interface builder provides you with a comfortable environment where you can set up your layout by creating constraints for each size class combination.
Problem
Some third party library is used. Some views disappear after their translatesAutoresizingMaskIntoConstraints are set to NO.
Don't have other autoresizingMask setting for my views in my own code; in the library, the autoresizingMask parts of code have been removed too. Instead, explicit bounds/center/frame are set for those views. There're no nib files, views are all programmatically created.
I know some other people solve similar problem by giving a thorough autolayout constraints set, but in my case, I mean to turn off autolayout and do it manually. No idea when autolayout is turned on.
Some people say that "by default, as your app launches, autolayout is switched off, and the system behaves as in iOS 5 and before. But if, at any time while your app runs, the system sees an autolayout constraint (generated in code or by the loading of a nib that has “Use autolayout” checked), the autolayout system is switched on, and from then on you’re running under autolayout." (Programming iOS 6 by Matt Neuberg, pages 383-384), but in my project I don't think there's any autolayout constraints left.
The code is bulky, but will upload some skeleton if necessary.
Thank you for tips!
If you don't want to use Auto Layout you have to set translatesAutoresizingMaskIntoConstraints to YES. Here's a reference:
This works through the property
translatesAutoresizingMaskIntoConstraints. When this property is YES,
which it is by default, the autoresizing mask of a view is translated
into constraints. For example, if a view is configured as in Figure
6-1 and translatesAutoresizingMaskIntoConstraints is YES, then the
constraints |-20-[button]-20-| and V:|-20-[button(20)] are added to
the view’s superview. The net effect is that unaware views behave as
they did in versions of OS X prior to 10.7.
For views that are aware of Auto Layout, in most circumstances you
will want translatesAutoresizingMaskIntoConstraints to be NO. This is
because the constraints generated by translating the autoresizing mask
are already sufficient to completely specify the frame of a view given
its superview’s frame, which is generally too much. For example, this
will prevent a button from automatically assuming its optimal width
when its title is changed.