Xcode 8 : Can i use Constraints and autosizing both in Single View? - ios

There is autosizing option available until you give any constraints to UI Component.
So can I use both for my ViewController?

You could, but you shouldn't
You can use constraints on some views, and autosizing on others, but be careful not to mix them on the same view, as that will cause issues (the autosizing information will be lost).
iOS takes care of autosizing views by creating constraints that convey the information of the autosizing to the constraints engine. This behaviour can be enabled or disabled by the aptly named translatesAutoresizingMaskIntoConstraints property.
You could try to add constraints to a view and still have it autoresize with the old behaviour by setting this value to true, but I suggest you use constraints for every view, as it can do everything the autosizing can, and much more.

Yes, you can (use a mixture of constraints and autoresizing on subviews within a single view) within Xcode 8. See:
02:38 https://developer.apple.com/videos/play/wwdc2016/236/
With Xcode 8, the translatesAutoresizingMaskIntoConstraints property for each view is automatically maintained by Interface Builder:
By default, when a child view is first added, the value of the property is true.
When the first constraint is added to the child view, the value is automatically set to false and the Size Inspector pane changes to the Constraints view.
When the last constraint is removed from the child view, the value of the property is automatically reverted to true, and the Size inspector reverts to the Autoresizing view.

If you create a view programatically, Xcode will generate constraints to satisfy autoresizing itself (translatesAutoresizingMaskIntoConstraints is set to true). However if you create a view in IB, Apple says:
If you add views in Interface Builder, the
system automatically sets this property to false.
To reflect that, any view added into IB before Xcode 8 has that autoresizing option hidded (or at least I did not see it for a while there).
But here is the thing:
Since Xcode 8, the option is visible (translatesAutoresizingMaskIntoConstraints is set to true) until you add any constraint, so the Apple's text above is not actually correct I guess.
So in a single view you cannot satisfy/use both. view(autoresizing and constraints)
In subviews you can use different for each one, but it will be a mess and I cannot imagine reasonable usage. view->subview(constraints) and subview(autoresizing)
That also means that you can use e.g. view(autoresizing)->subview(constraints)

Related

Can't add constraints in xib

I have a xib but I can't add constraints. When I control click and drag I can't do anything also the buttons at the bottom I can't do anything with it.
I'm using xCode 11.
Check if the layout option is set to automatic or not for the views/buttons etc for which you trying to add constraints. Attaching a screenshot for reference, hope this helps.
Please also pay attention to the Layout parameter in the Size Inspector. There are 2 kinds of values for each component in the xib: Inferred (Constraints) and Autosizing Mask.
If Inferred (Constraints) is selected, the view is added to the parent view without the autosizing constrains. It means no matter what autosizing you set for this view, it has no affect when added to the parent view. In fact, it is the same as "translatesAutoresizingMaskIntoConstraints" property set to false.
As the contrast, if Autosizing Mask is selected, the view's autosizing parameters you defined in the view will be applied when added to the parent view. It should be selected if you are using autosizing in xib.
I had this issue and I just figured out what caused it.
When I added a new button to my view controller XIB, I added the button to the open space next to the XIB and then dragged the button under the View in the Document Outline on the left. If you do this, for some reason, it doesn't let you Ctrl-drag to the view to add constraints.
If you add a new button and drag it into the view immediately, it should allow you to Ctrl-drag constraints into existence.
Try to embed the views in a view using the Embed in button. Set the Layout attribute of the new view to Autoresizing Mask.
Now you can use auto layout in the views inside the new view.
The new view should have the autoresizing mask with everything checked.
You should set layout property of your view to Inferred (Constraints)
For me on macos 10.15.6, XCode 12.4, this happens because I copied a NSViewController root view and tried to modify it as a child view. Seems like it also copies some hidden "can't be constrained" parameter.
So, just don't do what I did.
Xcode is very confusing sometimes but and when I was trying to pick from Layout option in the UI, it didn't give me Constraints, and as instead my Inferred was the same as currently selected option Autoresizing Mask which caused the most confusion:
But if you actually be brave and go ahead, instead of Autoresizing Mask it will activate Constraints and you are able to setup constraints hereinafter:

Set AutoLayout width constraint on top-level UIView of custom XIB from Interface Builder or code?

How do you set a width constraint on the top-level view of a custom XIB?
This would be Content View in the image below.
Clicking the Add New Constraints button doesn't let you specify a width. The option is disabled (along with other options).
Is this possible from Interface Builder? If not, is this possible from code? If not, that might explain some layout issues ...
Auto-layout sets the .translatesAutoresizingMaskIntoConstraints to true on the top-level view loaded from a custom XIB.
You want to set the .translatesAutoresizingMaskIntoConstraints to false via code when you load and use that view.
Is this possible from Interface Builder?
No. If you have a fixed size to give the view, then set its Size metric to Freeform and give it that size, directly.
If not, is this possible from code?
Yes, of course. You must have, somewhere, some code that loads the nib, obtains the view, and puts the view into the interface. At that point it is up to you to size and position it, and you can certainly use autolayout to do so, though no law requires that you do it that way; you could just give it a frame and leave things at that, or if the size coming from the nib is right, then you can leave it alone and just position the view with its frame origin or center.

How to prevent UIToolbar from getting resized when UIImageView displays an image?

I am building an app that allows a user to create memes (Udacity project: Meme Me).
The interface comprises of two UIToolbars (top and bottom) and a UIImageView that spans the space between them. The remaining UI elements are not relevant to my problem. Here is a screenshot of the app when it first launches:
When an image is loaded into the UIImageView both toolbars get resized and become smaller in height, as shown here:
What is causing the toolbars to resize, and more importantly, how do I prevent them from resizing?
Your toolbars could be resizing because unless you specify constraints on your UI elements (such as toolbars and UIImageViews), XCode interprets it in its own way and it shows you what it thinks is the best layout. We usually get around this problem by explicitly setting the following property of each UI element's to false:
MyUIElement.translatesAutoresizingMaskIntoConstraints = false
and then specifying the element's constraints programmatically. Note that MYUIElement is whatever you named your UIElement.
This tells XCode that you, as the programmer, want full control over the UI Element's positioning within its view.
You can prevent the toolbar from resizing by setting a constraint on it programmatically:
topToolbar.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
bottomToolbar.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
Of course you would replace topToolbar and bottomToolbar with whatever you called you named your toolbars, and 50.0 with whatever value suits your use case.
This is called AutoLayout. These two lines of code should be called after your toolbars have been setup (if you are creating them programmatically).
However, the concept of programmatic UI is probably not covered in a beginner iOS development course and you are most likely building this using a storyboard, which explains why your toolbars are changing out of control!
If you have created them using the Interface Builder (i.e. in your storyboard), then you can either modify their height constraint using the code above or by playing around with the layout settings in the Interface Builder, by clicking the button below:
If you decide to set your constraint through the storyboard as above, note that you might be told by XCode that you need to specify even more constraints (such as the width constraint) so that your toolbar's position is not considered "ambiguous" by the compiler.

Update Frames & Constraints in Xcode (Interface Builder)

I have been learning Xcode and iOS and things are going well with coding but I am confused about a few options in interface builder.
It seems that when I add a contraint I can choose to "Update Frames" and then either "Items of new contraints" or "All Frames" but it seems that I don't always need to do this... sometimes I do and sometimes I don't - I don't think I truly understand the concept. It seems to be optional. When is the case to choose it or not?
Once a constraint is added, then should that be it?
There is also a context menu (Resolve autolayout issues) (3rd item on the bottom on interface builder, represented by a triangle between 2 vertical lines) which also allows me to Force Update of constraint or update of frame. Why is this needed ? I notice the options inside are usually disabled so I presume this becomes active when there are issues ?
I have tried searching the internet and I can't find anything specific; the more I read, the more confused I seem to get.
Also, a sanity check: a frame is the bounding box of every single control (view) not just the viewcontrol, so every view (control) as its own frame. Is this correct?
I'll try to explain the concept of constraints and storyboard representation.
Constraints - are used to determine the position of UIView elements inside your view. For example, the vertical distance from top of the view to UIView element top. When you add constraint using the storyboard it plays 2 roles:
Positioning the element inside a view when your app runs
Positioning the element in the storyboard representation itself
Update Frames - is used when you want to update storyboard display so that it fits the currently applied constraints. When the display of the storyboard does not match the constraints a warning will appear.
Add missing constraints / Update constraints - will create/change the constraints applied on UIView element to match what currently presented in the storyboard. Kind of the other way around from update frames.
This answer is not a replacement for Apple's Auto Layout Guide
You do not have to click on "update frame" every time you add a constraint, if you do, it will update the frame of the view to whatever it should be based on the constraints. Yes, every view has a frame and it is the rectangle relative to the views superview.
More often than not you'll probably click on update constraints (Shift + Command + =), this will allow you to resize views that are already constrained, and have the constraints updated to match.

Views disappear when `translatesAutoresizingMaskIntoConstraints` set `NO`

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.

Resources