322

I opened an existing iOS project with Xcode6 beta6, and Xcode lists the following warning for both Storyboard and Xib files:

Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0

I tried addressing the warning by setting the width as explicit like below:

Yet this didn't resolve the warnings. How can they be removed?

Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
mono
  • 4,340
  • 3
  • 21
  • 49
  • 3
    I'm using XCode 6.1 and updated all my labels to Preferred Width = Explicit. This solved the issue for me. – djburdick Dec 18 '14 at 23:11

10 Answers10

373

Update 3:
This warning can also be triggered by labels that have numberOfLines set to anything but 1 if your deployment target is set to 7.1. This is completely reproducible with new single-view project.

Steps to Reproduce:

  1. Create a new single-view, objective-c project
  2. Set the Deployment Target to 7.1
  3. Open the project's storyboard
  4. Drop a label onto the provided view controller
  5. Set the numberOfLines for that label to 2.
  6. Compile

I've filed the following radar:
rdar://problem/18700567

Update 2:
Unfortunately, this is a thing again in the release version of Xcode 6. Note that you can, for the most part, manually edit your storyboard/xib to fix the problem. Per Charles A. in the comments below:

It's worth mentioning that you can pretty easily accidentally introduce this warning, and the warning itself doesn't help in finding the label that is the culprit. This is unfortunate in a complex storyboard. You can open the storyboard as a source file and search with the regex <label(?!.*preferredMaxLayoutWidth) to find labels that omit a preferredMaxLayoutWidth attribute/value. If you add in preferredMaxLayoutWidth="0" on such lines, it is the same as marking explicit and setting the value 0.

Update 1:
This bug has now been fixed in Xcode 6 GM.

Original Answer
This is a bug in Xcode6-Beta6 and XCode6-Beta7 and can be safely ignored for now.

An Apple engineer in the Apple Developer forums had this to say about the bug:

Preferred max layout width is an auto layout property on UILabel that allows it to automatically grow vertically to fit its content. Versions of Xcode prior to 6.0 would set preferredMaxLayoutWidth for multiline labels to the current bounds size at design time. You would need to manually update preferredMaxLayoutWidth at runtime if your horizontal layout changed.

iOS 8 added support for automatically computing preferredMaxLayoutWidth at runtime, which makes creating multiline labels even easier. This setting is not backwards compatible with iOS 7. To support both iOS 7 and iOS 8, Xcode 6 allows you to pick either "Automatic" or "Explicit" for preferredMaxLayoutWidth in the size inspector. You should:

Pick "Automatic" if targeting iOS 8 for the best experience. Pick "Explicit" if targeting < iOS 8. You can then enter the value of preferredMaxLayoutWidth you would like set. Enabling "Explicit" defaults to the current bounds size at the time you checked the box.

The warning will appear if (1) you're using auto layout, (2) "Automatic" is set for a multiline label [you can check this in the size inspector for the label], and (3) your deployment target < iOS 8.

It seems the bug is that this warning appears for non-autolayout documents. If you are seeing this warning and not using auto layout you can ignore the warning.

Alternately, you can work around the issue by using the file inspector on the storyboard or xib in question and change "Builds for" to "Builds for iOS 8.0 and Later" Xcode file inspector

Community
  • 1
  • 1
memmons
  • 40,222
  • 21
  • 149
  • 183
  • 15
    It's worth mentioning that you can pretty easily accidentally introduce this warning, and the warning itself doesn't help in finding the label that is the culprit. This is unfortunate in a complex storyboard. You can open the storyboard as a source file and search with the regex ` – Charles A. Oct 17 '14 at 01:31
  • @CharlesA. Good find. Interestingly, one xib still causes this error despite updating all labels with `preferredMaxLayoutWidth` property. – memmons Oct 17 '14 at 14:47
  • 6
    Is there any way programatically to configure a UILabel to automatically adjust preferredMaxLayoutWidth, without actually subclassing it or implementing it somewhere in layoutSubviews? If this is a behavior that IB can enable, that suggests there's a property or magic value that can be set. But nothing in the API docs or headers says that. – algal Oct 17 '14 at 23:32
  • 2
    @CharlesA. I've been testing with an empty project and found another label attribute that will trigger this warning: if `numberOfLines` is set to anything but 1, the warning will happen regardless of if you have `preferredMaxLayoutWidth` set or not. – memmons Oct 18 '14 at 15:44
  • 2
    @MichaelG.Emmons Strange, I cannot reproduce this with a clean project and a deployment target set to 7.1. Once I set the `preferredMaxLayoutWidth` to an explicit 0 the warning goes away regardless of the `numberOfLines` value. But perhaps this was fixed in the Xcode update this morning? – Charles A. Oct 21 '14 at 18:01
  • @MichaelG.Emmons In the alternately solution you mention about what does "Builds for" and "View as" stand for? Seems to working just find in iOS 7 devices while setting "Builds for" to iOS 8.0 and Later. – trgoofi Oct 22 '14 at 07:44
  • @CharlesA. I am seeing the warning go away after updating Xcode as well. – memmons Oct 22 '14 at 15:08
  • 2
    So... is the only solution to set the number of lines to 1 and change it from code? this doesn't seem professional – jomafer Dec 04 '14 at 10:29
  • 1
    Using Xcode 6.1 and Swift, I can tell you that the last solution, which is: " Alternately, you can work around the issue by using the file inspector on the storyboard or xib in question and change "Builds for" to "Builds for iOS 8.0 and Later" " works like a charm for me. – King-Wizard Dec 23 '14 at 20:02
  • I had way too many labels without preferredMaxLayoutWidth so had to use this regex. otherwise everything worked: – djburdick Feb 11 '15 at 00:31
  • @CharlesA. how do you search with Regex? Thanks – Adam Waite Apr 17 '15 at 09:41
  • 1
    Think this tutorial on youtube shows the hack to do to prevent the warning: https://www.youtube.com/watch?v=8q9vjYgRCa8 – Alex Cio May 11 '15 at 08:35
314

To Find the problem label(s) in a large storyboard, follow my steps below.

  1. In xCode's Issue Navigator right click on the error and select "Reveal In Log". (Note: @Sam Spencer suggests below, look in xCode's report navigator. Also @Rivera notes that "As of Xcode 6.1.1, clicking on the warning will automatically open and highlight the conflicting label". I haven't tested this).

enter image description here

  1. This will show the error with a code at the end of your storyboard file. Copy the value after .storyboard

enter image description here

  1. Next, reveal your storyboard as source file. enter image description here

  2. Search. You should be able to tell what label it is from here quite easily by looking at the content. enter image description here

Once you find the label the solution that worked for me was to set the "preferred width" to 0.

enter image description here

BTW, you can always quickly get the id of an interface item by selecting the item and looking under the identify inspector. Very handy.

enter image description here

starball
  • 20,030
  • 7
  • 43
  • 238
SmileBot
  • 19,393
  • 7
  • 65
  • 62
  • 2
    Why do you set the preferred width to zero rather than to the width shown in interface builder? – Yogurt Apr 08 '15 at 23:52
  • For hand holding regarding @Sam's comment, please see my response here: http://stackoverflow.com/questions/26920464/finding-cause-of-automatic-preferred-max-layout-width-is-not-available-on-ios-v/29971358#29971358 – Tom Howard Apr 30 '15 at 15:13
  • @TomHoward This info is redundant since it was already included in the last image. – SmileBot Apr 30 '15 at 15:55
  • @steve_thompson I debated not commenting since it included a part of your answer, but found the additional steps useful; I am hesitant to remove the intersection as it would leave my response incomplete on the other page. Thanks for your answer. – Tom Howard Apr 30 '15 at 17:29
  • @TomHoward No worries, just thought maybe you didn't see the last image. – SmileBot Apr 30 '15 at 17:34
  • 9
    Awesome answer! You can search for the object id directly from the IB view of the Storyboard. Just do a Ctrl-f. No need to open it as source code and then have to switch back to the IB view to change the preferred width. – AndroidDev Jun 05 '15 at 20:51
  • 1
    You can even open the storyboard and search for the id-values via cmd+f. – Tobias Aug 21 '15 at 13:25
36

You can fix this issue without opening the storyboard as a source. This warning is triggered by UILabels if numberOfLines !=1 and deployment target is < 8.0

HOW TO FIND IT?

  1. Go to Issue Navigator (CMD+8) and Select latest built with the warning enter image description here
  2. Locate the warning(s) (search for "Automatic Preferred Max Layout") and press expand button on the right
    enter image description here
  3. Find the Object ID of the UILabel enter image description here
  4. Open the Storyboard and SEARCH (CMD+f) for the object. It will SELECT AND HIGHLIGHT the UILabel
  5. Set Preferred Width = 0 "Explicit" as others suggested
Tibidabo
  • 21,461
  • 5
  • 90
  • 86
23

Solution it's quite simple

Just enable Builds for iOS 8 and Later

enter image description here

Alejandro Luengo
  • 1,256
  • 1
  • 17
  • 27
  • quite simple and destructive. Only 85% of iOS users are on iOS8+ https://developer.apple.com/support/app-store/ – aryaxt Jul 29 '15 at 22:15
  • 6
    @aryaxt I am sorry to say you are wrong. You can set a deployment target in project settings to iOS 7 or lower and change Builds for in IB Documents to iOS 8 and later and it WILL work on iOS 7. Please verify it and remove the downvote. You can check it here https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/chapters/DeployingSizeClassesonEarlieriOSVersions.html#//apple_ref/doc/uid/TP40014436-CH13-SW1 – Alejandro Luengo Jul 30 '15 at 08:42
  • 1
    As always the best answer is not the accepted one... :) Cheers! – HepaKKes Oct 23 '15 at 09:32
  • 1
    UPDATE for iOS9.3 and up: iOS7 devices no longer render storyboards with the above setting. This used to work prior to the 9.3 update. Looks like Apple changed something in their pre-release automated process. – Lukas Apr 14 '16 at 11:56
4

Now my Xcode version is 6.1. But I got this warning too. it annoys me a lot . after search again and again.I found the solution.

Reason:You must have set your UILabel Lines > 1 in your Storyboard.

Solution: set your UILabel Lines attribute to 1 in Storyboard. restart your Xcode. It works for me, hope it can help more people.

If you really need to show your words more than 1 line. you should do it in the code.

//the words will show in UILabel
NSString *testString = @"Today I wanna set the line to multiple lines. bla bla ......  Today I wanna set the line to multiple lines. bla bla ......"
[self.UserNameLabel setNumberOfLines:0];
self.UserNameLabel.lineBreakMode = NSLineBreakByWordWrapping;
UIFont *font = [UIFont systemFontOfSize:12];
//Here I set the Label max width to 200, height to 60
CGSize size = CGSizeMake(200, 60);
CGRect labelRect = [testString boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName] context:nil];
self.UserNameLabel.frame = CGRectMake(self.UserNameLabel.frame.origin.x, self.UserNameLabel.frame.origin.y, labelRect.size.width, labelRect.size.height);
self.UserNameLabel.text = testString;
ronan
  • 1,611
  • 13
  • 20
4

To summarize, for me following the two instructions above to change any instances where numberOfLines = 0 to 1 or greater, and manually adding preferredMaxLayoutWidth="0" to each instance of a label inside the storyboard source fixed all of my warnings.

Lynn S
  • 369
  • 4
  • 6
  • Dude u are a WIZZARD! Works even with a UIScrollerView as expected. BEST SOLUTION so far because I could leave my Nib's deployment's target on iOS7.0 – Yaro Jun 22 '16 at 01:17
3

Since I don't have a 50 reputation Stackoverflow wont let me comment on the second best answer. Found another trick for finding the culprit label in the Storyboard.

So once you know the id of the label, open your storyboard in a seperate tab with view controllers displayed and just do command F and command V and will take you straight to that label :)

Junaid Ahmed
  • 175
  • 1
  • 9
2

I got it working by selecting the original layout I had in the W / H selection. Storyboard is working as expected and the error is gone.

Be also sure that you are developing for iOS 8.0. Check that from the project's general settings.

This is where you should press.

1

I had this issue and was able to fix it by adding constraints to determine the max with for a label.

When dropping a multiline label in there is not constraint set to enforce the width inside the parent view. This is where the new PreferredMaxWidth comes into play. On iOS 7 and earlier you have to define the max width yourself. I simply added a 10px constraint to the left and right hand side of the label.

You can also add a <= width constraint which also fixes the issue.

So this is not actually a bug, you simply have to define the max width yourself. The explicit option mention in other answer will also work as you are setting this width value however you will have to modify this value if you want the max width to change based on the parent width (as you have explicitly set the width).

My above solution ensures the width is always maintained no matter how big the parent view is.

Matthew Cawley
  • 2,828
  • 1
  • 31
  • 42
1

For some reason, even if changing the iOS Deployment Target to 8.0 or higher, the Xib files don't adopt that change and remain with the previous settings in the File inspector

File inspector in the Xib after changing the iOS Deployment target

Therefore, you should change it manually for each Xib Afther the manual change

Once done, the warning will disappear :-)

Gutty1
  • 505
  • 2
  • 12