Interface Builder degrades storyboards, resizes and repositions views in small increments Interface Builder degrades storyboards, resizes and repositions views in small increments ios ios

Interface Builder degrades storyboards, resizes and repositions views in small increments


The most interesting clue in this mystery is that it seems especially bad when you open the same storyboard on a Retina display as opposed to a non-retina display.

At first I was going back and forth between a 4k iMac and a pre-retina Macbook pro and was getting a large volume of changes (~300 lines altered each time).

Then I simply dragged the xcode window from my main monitor (4k/retina) over to my second monitor (2560x1440, non-retina) - and while the window was the same size, xcode resized all the elements and complained of ~50 misplaced views. I moved it back to the retina display and about half of the "misplaced" errors went away, but half remained. The re-scaling - as you suggest - degrades the underlying data.

If you've got multiple developers working on the same file, this is bound to happen frequently.

The solution? This is likely all on Apple to correct - I haven't run into any settings that would mitigate it otherwise.


This seems to be a bug related to Interface Builder's serialization of CGFloat values. The size and position values for view frames are floating points. But their values are always integers. The internal graphic manipulation requires them to be floating point for the transform math to work, but everything is always expressed in terms of round integer point values.

When these floating point values are serialized to the storyboard XML, IB often serializes the values as integers, but occasionally serializes them as floating point numbers too. I'm not sure why it makes the decision to do it this way when it does, but it's less common. In my example frames above, 3 of the values ended up being floating point, while the others are integers.

Also seen in my examples, often the floating point representation will be changed to be serialized as an integer instead. This is where I believe the bug is found.

One thing I noticed with the way view frames were changing, they were tending to move to the left or shrink in size. So the values are mostly getting smaller. You can see in the examples I provided, this is most always the case.

Floating points don't have the precision to express integer values exactly, but are accurate out to several decimal places. So while sometimes integers are expressed as those in my examples as slightly higher than the integer value (i.e. 384.00001078580522), others are expressed as slightly lower than the integer value. Here's an example of a frame change that IB made:

<rect key="frame" x="457" y="7" width="291" height="30"/>                      |                      V<rect key="frame" x="456.99999985252464" y="7" width="291" height="30"/>

While this particular change didn't seem to modify the frame's value directly. Both numbers are essentially equal to 457. What I think is occurring is when this XML is re-parsed when the storyboard is opened again, it could be truncating the 456.99999985252464 value and reading it as 456. This is then causing the values to get progressively smaller, shrinking the sizes or shifting the position of the frames to the left or up.

Of course this is just a theory and doesn't give a reason for why Interface Builder is doing this. It seems to have begun since the recent Xcode 6 release. Also, it doesn't explain how it went from 8 to 7.5 on one example or even the one time it went from 274 to 276 in my last example. But for the most part, most of the changes tend to be in the downward direction.

I'm filing a bug with Apple to have this looked into.


I might have an answer to this problem. Its a lesser know feature of opening the apps in low resolution mode. We recently had a similar problem wherein the content view of the table view cells had a 0.5 extra for the height when the separator line is set to default or single. When its set to None then this problem was not there.Steps1. Drag a default TVC to storyboard. Check the height of the content view of the table view cell. It will be 43.5.2. Set the separator line for the table view to None. The content view of the cell changes to 44.

Now quit Xcode and set the Open in Low Resolution mode in Finder Get Info window for the Xcode app. Now if you follow the same steps above it will show the height of the content view for table view cell as 43.

When there are different team members working on retina and non-retina displays you would simply get the storyboard files as modified just because you opened the storyboard in retina display. One workaround for this is to turn the Open in Low Resolution mode and work. But then it defeats the purpose of having a retina display though but better than having storyboards marked as modified even though you have not changed anything.