I am migrating this to Xcode 9.
The button is clearly not going to be clipped, why is it giving me this warning?
Buttons with text and a fixed width can easily be clipped.
Whenever you decide to modify the text through code or decide to use Dynamic Type for the button's text, this can be a valid issue.
Generally speaking, it's a bad idea to set a fixed width to something that can vary.
Related
I have a window with a textview in a scrollview and two buttons. I have added constraints at all sides, leading, trailing, top, and bottom. For the buttons I have fixed width and height, and distance to bottom and edge.
I want it to look something like this:
And this is what Interface Builder keeps giving me:
It also keeps offering to fix ambiguities by adding missing constraints, but actually clicking the button has no effect. No constraints are added. The error (and the offer to fix it) remains.
I've tried added the constraints it is asking for, although I can't see why they would be needed and at least the buttons already have (fixed) width constraints. But I keep getting errors and the window keeps getting shrunk to nothing.
When actually running the program, the window looks fine. But I suspect these autolayout errors have something to do with this problem: NSTextView in magnified NSScrollView breaks on resize
The project is here: https://github.com/angstsmurf/spatterlight/tree/helpviewtest
(The branch helpviewtest is a cut down test case created specifically for this problem.)
You have a Text view embedded in a Clip view embedded in a Scroll view, none of which have an intrinsic content size.
IB has no idea what's going to go on at run-time.
So, while everything looks great when you run this, your code will have supplied enough information to lay things out as desired.
To get it to "look right" in IB (and avoid the errors/warnings), you can give the ScrollView a Placeholder Intrinsic Content Size:
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
Recently, I encountered a problem with the Interface Builder which I failed to solve. I'm using a UICollectionViewController and whenever I add a Cell it immediately shows a orange rectangle (indicating a auto-layout update). Updating the frame/cell doesn't change anything. The warning associated with the orange marking reads "Expected: height=Y, Actual: height=X" where Y is always exactly X-100. That is: When I set a custom cell height of 193, it says "Expected: height=93". This happens no matter which size I enter.
The problem with this is that I have many difficulties with the subviews and their constraints. For instance, if I add a subview with the constraint to keep the same height as the cell, it will be shown as 93 (the expected height), even though my cell should be 193. Layouting becomes impossible.
I tried adding a new cell, same issue. I tried removing every subview and re-adding them, nothing.
Any ideas are highly welcome.
Thank you very much!
Solution found ! (Xcode 9.2)
The bug seems to only happen when you try to embed the UICollectionViewController in a Container View in the storyboard. The workaround is to remove the segue while you set your constraints, and re-add the segue once your constraints are well set.
I also think that setting UICollectionViewController size as Freeform could be responsible of the bug. If so, try to set constraints before changing the size.
Hope this helps !
I'm not sure if this solved it, but the warning and issue disappeared once I did the following:
Select the CollectionViewController in Interface Builder and set the size to freeform and make the height larger, large enough to show all your template cells. (Plus: maybe refresh the views). That solved the issue for me.
In my case, I have added two collection view cell, withing collection view Controller.Only setting the view controller to free form wont help us. Need to update the size, to get rid of the warning.
updating collection view cell frames, wont help us. Warning will be continuously changing its length.
I tried to work without considering the warning, as I have set my collection view cell size programmatically and it does working as expected.
I think it's just a strange bug
I delete the collectionViewController in SB, then create a new one, the problem disappear
This is a common bug with Interface Builder. I don't know the exact cause, but I believe it's something to do with placing collection views inside arrangement views that do not have an exact size. I've seen it when putting them in scroll views, stack views and container views.
There is a simple fix, although I believe this to be a bug in IB that ought to be corrected by Apple rather than hacking around it. The solution (for me at least - your mileage may vary!) is to place the collection view inside an ordinary UIView and pin its edges to it, then place that parent view in the position that you wanted your collection view with all the constraints it required.
I usually found that there were actually no auto layout issues at run-time, which is why I believe this to be purely an Interface Builder bug.
I have NSTextField with left, right and top constraints defined (no bottom constraint set). I need NSTextField to grow if content can't fit in it and decrease size if there is unused space left.
Now I have: NSTextField automatically expands with strange behavior if it has multi-line text or too much content, also NSTextField doesn't decrease own's size on window resize.
I haven't found any simple solution written on Swift to solve that problem (I have a lot of such labels with constraints), at iOS everything was working with usual text labels and constraints.
I've created simple project for that question that you can see the problem: [Download Text.zip]
The solutions I've found but not used:
You can try to calculate possible TextField height and set height constraint for it. Problems of that solution:
Possible height calculations are inaccurate, sometimes you calculate incorrect height.
Solutions are written on Objective-C with some complex code.
Run .sizeToFit() on each window resize or text change action. It's not working because .sizeToFit() always compress all text to single line.
Use NSTextView instead of NSTextField. It's good way, but:
I don't need scrolling, editing and other functional of NSTextView. I don't want to call to complex component for simple label.
NSTextView always wants height or bottom constraint, I don't know bottom constraint because content can expand down with new text.
I haven't find full solution to make NSTextView's behavior like I want :)
According to Mac OS X Release Notes (section NSTextField intrinsicContentSize improvements) it’s known bug when height of NSTextField is changed, but width is remained the same. We have two ways to fixing it:
We can specify maximumNumberOfLines to a value that makes sense. That is not good way to us because we don’t know actual number of lines and don’t want to calculate it.
We can set preferredMaxLayoutWidth to a real value. I’ve ended with such code:
Code:
override func viewDidLayout() {
super.viewDidLayout()
textField.preferredMaxLayoutWidth = textField.frame.width
}
After much reading and experimenting, I still cannot get a simple TextView to resize fully in the horizontal direction using Xcode 5.0.2 in Mavericks. It resizes partially as the window is resized, then stops with long lines wrapped around even though my containing NSScrollView continues to resize as expected (it has four default constraints and no horizontal scroller).
Can anyone point me to a simple code/IB+AutoLayout example, preferably just a window containing just an NSTextView dragged in from the IB template library --- one that works? The Apple TextEdit sample code is almost irrelevant for this purpose although it does resize horizontally quite well. Also, there is the clip view for which I can find little information.
Any other tips appreciated.
Thanks.
Answering my own question:
Turns out that my problem had nothing to do with AutoLayout and little to do with NSTextView. It was the textfile I was using to test my code! This file was composed of records with tab-delimited fields.
Turns out that NSTextView comes with a default NSParagraphStyle with predefined tab stops that end at character 56 whereas my test file had tabs beyond that. Therefore, my lines wrapped around at the last defined tab no matter how much I stretched the window.
After changing my search terms, I found what I needed at the following links:
Premature line wrapping in NSTextView when tabs are used
How to have unlimited tab stops in a NSTextView with disabled text wrap
Apologies for wasting bandwidth.
Not sure why such a simple thing does not work in your case, but nevertheless here's what I did in Xcode to get an NSTextView follow window resize:
Create a new project (not document based in my case but it doesn't really make a difference)
Drag a NSTextView from the palette to your window. Align all four edges with the window edges.
Open the "Add constraints" pop-up (second button from the segmented control on the bottom-right part of your IB view.
Each of the four spacing constraints should show a number equal to the distance of your text view from the container window. If you aligned them, this number should be either 0 or -1. Click the down arrow for each of them and select "Use Current Canvas Value". Do it for all four. Make sure no other constraints are selected.
Click on "Add constraints" on the bottom of the panel.
Run your project. Your textview should resize with the window.
Also, as Jay's comment mentions, make sure you do not have any "leftover" constraints in your view. You can check this either by observing Xcode's warnings, or manually by inspecting your view's constraints by going to the Size Inspector tab (4th tab on the Utilities bar).
If you need to have your textview arranged in a more complex layout, it might be worth taking a look at the AutoLayout Guide.