Understanding "firstBaseLine" vs. "baseLine" AutoLayout Constraint - ios

I've created the following view that looks as follow:
And used Add missing constraints t automatically add constraints.
I am pretty new in iOS world and I'm trying to configure out how constraints work.
On document outline, I can see the added constraints:
I click on label UR and Size inspector show me following:
What is the difference between constraints aligned by first baseline to UL and aligned by baseline to UL? When I click on the size inspector on constraints button, it shows me the same line.

From the Apple Docs:
NSLayoutAttributeBaseline
The object’s baseline.
Available in iOS 6.0 and later.
NSLayoutAttributeFirstBaseline
The object’s baseline. For objects with more than one line of text, this is the baseline for the topmost line of text.
Available in iOS 8.0 and later.
Here is also a screenshot of the difference when aligning to a three line label. The upper green label is using NSLayoutAttributeFirstBaseline and the lower green label is using NSLayoutAttributeBaseline. These are the only constraints on the two green labels besides they are both Horizontally pinned 40 from the Pink Label

I don't recommend ever using "Add Missing Constraints." It is a very unpredictable wizard that DWIW (does what it wants). Learn each constraint and add it by hand. Ctrl-drag between objects in the scene hierarchy; use the constraints inspector and edit numeric values; use 'Update Frames' from the triangle pop-up; delete constraints from the inspector; repeat until you get it.
firstBaseLine refers to the top baseline of a multi-line object:
Storyboard warning : First baseline layout attribute before iOS 8.0
if the label or text field involved only has one line, it's a useless constraint.
When you want two side-by-side one-line blotches of text to align vertically, even though their font sizes, ascenders, and baseline descenders may differ, use baseLine alignment. It will look natural like the strings are on the same line.
Bottom, Top, and Center vertical alignments are also possible and more appropriate for non-text objects.

In the image you can see a simple visual example using both baseline constraint.
It is quite illustrator.

Related

Swift Storyboard - Centring an Icon and multi-line text horizontally

I am trying to create an Android-esque Snackbar. All the behaviour is correct but I am left with a layout issue. I have actually broken this out into a test app to simplify things a bit.
The bar is pinned to the bottom of the view and contains an Icon (UIImageView) along with some text (UILabel). This text can be up to 2 lines max.
For example, it should be able to exand out like this:-
However to further complicate things, i need it so that the icon and text are centred within the red bar and then spread out from the centre until such point that it needs to wrap. Note that there is a padding to the start of the icon and end of the text to prevent it touching the sides. An example of centred content would be..
I haven't been able to get the correct layout. I think the issue has been trying to centre the two items whilst simultaneously conforming to a width that doesn't exceed the edge bounds, causing a constraint conflict. I have also tried embedding the icon and label in a horizontal stack view but couldn't seem to find the correct fill option whilst centring everything.
I have even tried using NSAttributed string and adding the image to the text itself but when the text wrapped, the icon was being resized and/or misplaced.
As you can see, i have been doing this in Storyboard but i am more than happy to do this programmatically if it serves this purpose better.
Created this Demo for reference , it's a simple task of making a nested view inside the red view with a centerX constraint of priority 1000 and a leading constraint with 999 priority
Now you have this effect

Can't set margin from the edge

I followed Apple website's guide for Swift
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/BuildABasicUI.html#//apple_ref/doc/uid/TP40015214-CH5-SW1
After I placed the 3 objects on the drawing board and stacked them, it aligned with the left margin nicely but after I set the constraints for adaptive interface, it aligns with the very edge of the screen. Any help?
https://i.imgur.com/eRH9Wor.png
but after I set the constraints for adaptive interface, it aligns with the very edge of the screen. Any help?
You just haven't configured the constraints properly. It's hard to say exactly what you've done wrong without seeing how your constraints are set up, but I can give an example of what they should look like. Here's a button in a view, constrained so that the button is inset 20 pixels from the top and leading edges of the view. With the button selected in Interface Builder, we can see the constraints:
And looking at the constraints in the Size inspector:
(The button looks a little different from what you might expect because this happens to be a macOS project, but the constraints work exactly the same way as they do in iOS.)

Autolayout view dropping down

I’ve built a simple login screen layout. In a vertical direction, there is a logo at the top, followed by 2 text boxes for email and password and then a submit button.
There is an outer container which container 2 more container views, one for the logo and one for the text boxes and button.
With auto layout, I have got the layout displaying correctly in Xcode, with the logo container above the input details container. However, when I launch the app on the simulator or on a device, the logo seems to drop down over the top of the text boxes.
Xcode is telling me I am missing a constraint for containerLayout for y position or height. I’m unsure if this has any impact on the problem.
It would be extremely useful if someone could explain why the logo is dropping down. I will include an image of the constraints in place.
As an absolute minimum, you should:
Add leading, trailing, bottom and top constraints to the logo image view.
Set vertical content hugging priority for the text fields to required (1000).
Add bottom constraint for the sign in button.
You definitely use too much of center X, and equal widths, this obscures entire picture of your layout. If you want to make it simpler and more readable include the following modifications.
Remove center X, center Y and equal widths from the logo image. As you will see it won't break anything but only simplify the layout.
For both text fields, remove center X and equal widths constraints.
For both text fields, add leading and trailing constraints to the superview
Repeat last two points for sign in button.
If you are targeting iOS9 or higher you can use a stack view to layout text fields and buttons. Below you can find the final result. Of course, you can introduce a lot more improvements to this layout but I don't want to reinvent it here.
Update
To configure bottom constraint for the logoDetailsLayout just add it as normal. Sometimes when views are not aligned as they should be Xcode gets lost. In this case, you can double-click this constraint and fix it in the attribute inspector.
This is how I configured it.

Xcode 9 - "Fixed Width Constraints May Cause Clipping" and Other Localization Warnings

I downloaded the new Xcode and in Interface Builder I'm having a ton of problems with warnings that say things like:
Fixed Width Constraints May Cause Clipping
It looks like this:
I do have localization for several languages and I understand the warning that in another language a label's size may change, but my app doesn't have this problem. I ran and tested it in Xcode 8 yesterday, it was fine. I don't want to spend hours and hours adding pointless new constraints.
Any suggested solutions?
I was getting the same warnings even without multiple languages in my app, which led me to find out what was really going on. . .
There are a few different things going on here. I was able to silence the fixed-width warnings in my own app by changing the width of the object spacings from fixed width to greater than or equal or less than or equal.
This can be done by selecting the object in interface builder, going to the size inspector and changing it there:
Or, select the constraint from the document outline, go to size inspector, and change it there:
As far as the warning at the top of your screenshot:
Fixed leading and trailing constraints with a center constraint may
cause clipping
Here is a screenshot from my own app in which I was getting the exact same warning:
I had the label with the # sign set to leading and trailing to the buttons but also to align the center with the rating label. Once I removed the center alignment constraint, the warning disappeared, but I was left with an improperly laid out set of objects.
It is then that I resigned myself to embrace the Stack View. As annoying as it is to use, when you get all of the constraints and settings right, it lays out beautifully and with no warnings.
Edit
As Repose writes in the comments, sometimes simply adding >= 0 will be what you need, as you are making sure two elements do not overlap.
You can try Disabling "Respect Language Direction" on per Constraint basis to silence the warning and see if it helps. Select your constraint and open Attributes/Size Inspector. Please see image attached.
If you are not planning on localizing your app to other languages, then this solution should not have any drawbacks. For localized apps you have to be more conscious of your label and font sizes.
p.s. This solution works for iOS. For macOS try >= or <= to silence the warning.
p.p.s. Labels in the picture below are much easier to create using AutoLayout and attributedString property on a single UILabel or UITextView using NSMutableAttributedString. The image is for demonstration purposes only.
For labels and buttons which are localized this warning makes sense and you should provide the necessary constraints so your labels don't overlap. If they don't overlap now they might in the future, so it won't hurt to provide the constraints.
Xcode helps you add these constraints automatically:
In the document outline of your storyboard click on the yellow arrow and either choose "fixed leading" or "fixed trailing", depending on where the text is on your screen (left or right). This will fix it for most issues.
If you have this issue with a Button without any text (only image), try to remove the "default title" which might still be set for the button:
With Labels, you can set Lines is 0 and Autoshrink properties is Minimum Font Size to remove Fixed Width Constraints May Cause Clipping warnings, like this:
Another quick solution !
For a UIButton by changing the title from plain to Attributed text also resolved my issue:-
I know this question has already been answered but what I did to fix this error in my case was to add the "Aspect ratio" property and then eliminate the width or height constraint this worked pretty well and was less effort, and I managed to keep the same output and adapt my view for the different devices.
Swift 4 , Xcode 9.1 :
About this issue, I think your object don't know what it's the correct center position in the context of it's superview, and using remove, greater than or other leading/trealing settings most of times don't work correctly. First, you must check the correct constraints of your superview.
If your superview/s are correctly setted, you can try to "explain" to your object what is the correct position in the view by setting the "horizontally in Container" constraint:
If you need fixed width constraint for button just set width constraint priority to 700.
I had the same problem, but when I changing to >= it automatically set the constant to 0, if I choose 60 for instance, the warning appears again. So I was in a loop with the problem.
I could fix embedding my Label in a View
Editor > Embed In > View
In Label I set Top, Bottom, Leading and Trailing with constant = 0
In View I set the constraints that I was expecting before.
I had the same problem when moving to Xcode 9 and found an approach that's useful for certain kinds of layouts. In my case, I wanted a table header in which two columns (UILabels) were of fixed width and another was of variable width. Regardless of how I specified column widths (including using constraints greater than or equal instead of equal, etc.), I kept getting the warning about possible clipping. In my case, I wanted the variable width column (UILabel) to clip if necessary. I could have just ignored the warning, but don't like doing that.
The approach that worked here was to create a UIView with appropriate size constraints and embed the UILabel as a subview in the UIView. Then truncation happens if necessary and I get no warning. This works whether the UIView/embedded UILabel is in a StackView or not.
This is essentially the same approach as that of Haroldo Gondim but here you can see it also works with or without StackView.
The following image shows the approach, with and without StackView. "SpacerName" is a variable width UIView containing a label and "SpacerPD" is one with a fixed width of 80. [Colors are not significant; just there to show where the views are.]
As you can see in the image below, I was having the error "Fixed Width Constraints May Cause Clipping" because although I had set my textbox to be vertically centered and my label to have a left margin constraint, I hadn't defined a constraint for the text box in relation to the label, so XCode was alerting me that the textbox could clip (be rendered above) the label.
After adding the left constraint to the text box to always stay some distance apart from the label the error was considered solved by XCode and it didn't bothered me with the constraint warning anymore.
I had a similar issue when trying have the button with the same paddings from the edges of the super view.
I've ended up using horizontal center constraint and equal widths constraint to the super view.
To Fix The Error: Fixed Width Constraints May Cause Clipping” and Other Localization
You need to select the view/object, go to the "Show Size Inspector", find the Width Constraint and set the Constant to Greater or Equal to:
To Fix The Error: Leading/Trailing constraint is missing which may cause overlapping with other views
This means that the view/object Xcode is complaining about, is missing a Leading or Trailing Constraint to a neighboring view.
While holding control, drag to a near by view/object
Add a Leading or Trailing Constraint

Xcode 4 and Interface Builder: Editing Vertical Spacing Constraint (Anchor Top, not Bottom)

I've got a widget that is not laying out correctly on device (its looks OK in IB, but its not quite right). The widget is a label and its located about mid-screen. Interface Builder gave it a Vertical Space Constraint with a 'Bottom Anchor'. Here, bottom means bottom of the screen (rather than a widget below, or anchor to top screen).
I'm in the inspector, but I don't see how to change to a top anchor (preferably, to the widget above). I tried reading Apple's docs and Editing Constraints in particular, but it was a confusing and did not explain how to make the change (or I missed the discussion - which was 7 sentences).
Below is a screen capture under Interface Builder showing the Vertical Space Constraint anchored to the bottom of the screen. And its attributes leave a lot to be desired - Equal, Constant and Priority don't really help.
Does anyone know how to edit constraints? Specifically, I want to (1) change a vertical spacer's anchor from bottom to top; and (2) anchor against the widget above, and not the top of the screen.
Select the "Embedded" and the "Calculated" element together by shift-clicking.
With those two elements selected, use the constraints menu:
This menu, together with careful selection of elements, is central to happy editing of constraints in IB. In your case, choose the central item, the Pin menu. Choose Vertical Spacing - this will create a new constraint on vertical spacing between your two elements. Alternatively, select a single element and pin "Top space to superview" to pin to the top instead of the bottom.
You can now select and delete the vertical spacing to the bottom of the view. IB wouldn't let you delete this before since you have to have a complete, non-ambiguous set of constraints. After adding your new vertical spacing constraint, you now have this.
To illustrate further, here is an empty view controller, with a single text field which I have dragged on:
All of the constraints are purple, which means IB has added them for me (they are System constraints) and they can't be removed - they are the minimum constraints needed to position and size the text field.
Now, I'll select the text field, and pin the top space to the superview:
Now you can see that the two vertical space constraints have changed to blue (they are now user constraints) and they have a thicker appearance in the editor. This means that one of them can be deleted. I select the constraint for the bottom space and hit delete:
Note that this still has the appearance of a user constraint - but if I try to delete it, IB will automatically recreate the system constraint pinning to the bottom of the superview, getting us back to square one.
I have written about this, and similar autolayout topics, here.
I got one word for Autolayouts. If it works, it works but if it does not, then use the old fashioned way (use code)

Resources