Strange behaviour in Storyboard (Missing view when running app) - ios

For the last few months I have been doing all of my layouts in code to practice with autolayout.
I have decided to go back to Storyboards and am regretting it already :-). I have been trying to do a layout with multiple views including a UIStackView and was getting many errors. I thought maybe I was doing something wrong with the StackView so I decided to delete everything apart from a button and label.
The simple view with a label and button can be seen below:
As you can see, the constraints on the label are very simple. The button in the top right (where the blue is) just has top space and trailing space. However when I run the app the label is not seen:
I am also constantly getting: An internal error occurred. Editing functionality may be limited.
Has anyone else experienced this odd behaviour?

You have set the leading and trailing of the label . This will definitely happen because you have set the wrong constraints. Check the size of your view Controller where you have set the constraints, its (Any width , Any height).
Now, check in which size you are running, its (Compact width, Regular height). If you run it in a iPad you will find your label. Since, you have not fixed the width of your label, the label gets compressed when it is run. Try setting the width of your label and remove either the leading or the trailing constraint.
Else instead you can fix your width and select either the leading and trailing and set it to "less than equal to " rather than "equals to".
While designing imagine yourself holding the object keeping in mind about all possibilities that can occur and then set the constraints accordingly. A user can run your application in any size iPhone and iPad. So, the design should be such that it doesn't affect your objects in it.
If any problem occurs try view debugging then you can definitely find out where you have done wrong.

You may need to remove label's leading & trailing space, and add add constraint call "Center Horizontally in Container" if you want to center the label.
You can learn more about autolayout in here if you do not know it well.

You have hard coded leading and trailing constraint constants. They add up to 518. That probably makes your label width negative. You don't see it in Storyboard because you're using the inferred simulated metrics. You'll see it right away if you change to an 3.5 inch iPhone.
I think a better approach would be to remove the leading and trailing constraints and center the label horizontally in the superview. You can set a fixed width on your label if you want.

Related

NSLayoutContraints: How to position a bottom view below the higher of two labels?

I am working on an iOS 11+ app and would like to create a view like in this picture:
The two labels are positioned to work as columns of different height depending on the label content. The content of both labels is variable due to custom text entered by the user. Thus I cannot be sure which of the the two labels is higher at runtime and there is also no limit to the height.
How can I position the BottomView to have a margin 20px to the higher of the two columns / labels?
Both labels should only use the min. height necessary to show all their text. Thus giving both labels an equal height is no solution.
I tried to use vertical spacing greater than 20px to both labels but this leads (of course) to an Inequality Constraint Ambiguity.
Is it possible to solve this simple task with Autolayout only or do I have to check / set the sizes and margins manually in code?
You can add labels to stackView
One way to do this is to assign equal height constraint to both label. By doing this height of label will always be equal to large label (Label with more content).
You can do this by selecting both labels and adding equal height constraint as mentioned in screen short.
Result would be some think like below
The answer given as https://stackoverflow.com/a/57571805/341994 does work, but it is not very educational. "Use a stack view." Yes, but what is a stack view? It is a view that makes constraints for you. It is not magic. What the stack view does, you can do. An ordinary view surrounding the two labels and sizing itself to the longer of them would do fine. The stack view, as a stack view, is not doing anything special here. You can build the same thing just using constraints yourself.
(Actually, the surrounding view is not really needed either, but it probably makes things a bit more encapsulated, so let's go with that.)
Here's a version of your project running on my machine:
And with the other label made longer:
So how is that done? It's just ordinary constraints. Here's the storyboard:
Both labels have a greater-than-or-equal constraint (which happens to have a constant of 20) from their bottom to the bottom of the superview. All their other constraints are obvious and I won't describe them here.
Okay, but that is not quite enough. There remains an ambiguity, and Xcode will tell you so. Inequalities need to be resolved somehow. We need something on the far side of the inequality to aim at. The solution is one more constraint: the superview itself has a height constraint of 1 with a priority of 749. That is a low enough priority to permit the compression resistance of the labels to operate.
So the labels get their full height, and the superview tries to collapse as short as possible to 1, but it is prevented by the two inequalities: its bottom must be more than 20 points below the bottom of both labels. And so we get the desired result: the bottom of the superview ends up exactly 20 points below the bottom of the longest label.

Constraints with static cell are ambiguous

I'm having some problems with properly setting up my static cell the way I want it while making it look good for different screen sizes.
Somehow I don't seem to get how constraints are supposed to work.
One of my views contains a UIViewController with a table view. However, if I change my preview device in the storyboard to, say, an iPad, the table view doesn't get resized. Am I supposed to handle stuff like this from code only or is there a way to handle this from the storyboard (like setting width and height to always fill)?
I'm trying to set up a static cell so it looks good on devices with different screen sizes. Things work well enough when I have only two elements (e.g. one label left and one label right - just like in the standard template), but as soon as I add more things, I'm running into a lot of warnings, e.g. that width and height are ambiguous.
To me, it seems like I'm missing some key concept of constraints.
Look at the picture provided. What I want is the following:
Date to be a certain distance away from my left table border
The Stack View of volume + pic in centered in the middle
pic & price & label (there is one more for the measurement) to be represent the right label
I'm unable to actually try this at the moment but here's the path I would go.
Date:
Fixed Top, Bottom, & Leading to Container constraints to 8 (or whatever you'd like).
Volume Stack
Fixed Top & Bottom to Container constraints to 8.
Price Stack
Fixed Top, Bottom, & Trailing to Container constraints to 8.
You'll have some overlap issues with smaller screens at this point. You should get the "Red Circle" to suggest which constraints to add. Click and read each one and it will be specific enough to walk you through which you want resizing, resetting priority, etc.
*I hate dealing with constraints.
Good luck! I'll try tonight to see if I gave an acceptable answer. :)

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

UIScrollView with multiple multi-line labels and AutoLayout?

Is there a way to achieve this? I have tried literally everything and nothing has worked for me yet.
So basically what i want to do is the following: I have a scroll view with some labels in it. All the labels get their text from a server and I have set their number of lines to 0 so that they change their height according to the amount of text. However, this does not affect the scrollview content size(even though my labels have constraints set up to the bottom,top,leading and trailing of the scrollview) and the labels go off screen and I am unable to scroll down. Can someone point me in the right direction to how I would set up my constraints, my view hierarchy and etc?
Any help is much appreciated! :)
Late, but this solved it for me:
Set leading (I have a 32pt inset), trailing and top constraints. The trailing will not actually seemingly do anything..
Make the trailing Greater Than or Equal to avoid localization alert.
Finally, add a new Equal Width constraint to the label matching the scrollview. Use the constant to subtract the required padding (I used 64 due to mirror my leading inset).
And voilà! The Label will align correctly both in IB and in-app.
In Scrollview the last view's bottom constraint is so important. You should set its priority to 250 and put it to Greater than or equal.
Remember you should only change the bottom constraint of the last view, which in my case it's the continue button.
I would consider using UITableView instead, it has several benefits:
It allows for reuse of cells, if all the cells look the same
It manages recycling of cells when the number of values you're getting from the server increases (decreases memory pressure when number of cells becomes substantial)
It allows for more flexibility with the content (it's quite often for design to change last second or to evolve over the course of the project)
Most importantly, UITableView support auto sizing cells (as of iOS8), you need to specify the constraints between the label and the borders of the cell
There are several resources to start with:
http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout
https://www.captechconsulting.com/blogs/ios-8-tutorial-series-auto-sizing-table-cells
http://www.appcoda.com/self-sizing-cells/
Use a container view in a scrollView
Add constraints to superview (leading, trailing, top, bottom, height,width)
Make IBOutlet of constraints that you are going to update.
Add you all labels inside that view.
Update constrains/frame of your label so that it fits the text.
How much you increase the label height you should increase the container height too.
If the label count is not fixed use custom label class to add subview.
Perhaps you should need to understand how ScrollView works in Storyboard with autolayout.

UIDynamicAnimation issue with autolayout

I am new to autolayout.
I have got a view hierarchy working fine with autolayout.
I got a container view displaying a menu. I am animating this view using Dynamics to make a pop effect: the view grows from a tiny size to its target size.
The effect is great. The problem is, since the view needs to be shrink to a tiny tiny size (like 5x5 at the beginning), all the first part of the animation cannot resolve my subviews constraints (like leading AND trailing space cannot be both 10 because the view itself is 10).
I don't care if at this minimum scale the layout is messy or exceeds the view frame but I don't know how to define my constraints to make it work.
Like, is there a way to tell autolayout:
This trailing space should be 10 but if you can't then ignore it
Or something like that. Since I know which constraint should be ignored it would be great if there is a way to tell it to autolayout instead of having the warning and letting the OS "guess" which constraint to drop.
I am sure I could do everything programmatically by skipping all these constraints before animation, animating, and putting them back but since it is a big table view with many rows there are so many table view cell inner contraints to consider that it would really be hard to achieve.
Any insight / help / pointer on this would be great.
This trailing space should be 10 but if you can't then ignore it
The above statement is ambiguous, we need to define when the drawing system needs to add constraint for trailing space to 10 and when to ignore it, specifically.
This is obviously possible through coding it programatically. But,
You can set constraints using inequalities like "greater than or equal to" or "less that or equal to", and that would hopefully solve you problem.

Resources