UFO ET IT

Interface Builder는 스토리 보드를 저하시키고, 뷰의 크기를 조정하고, 조금씩 위치를 변경합니다.

ufoet 2020. 11. 18. 21:51
반응형

Interface Builder는 스토리 보드를 저하시키고, 뷰의 크기를 조정하고, 조금씩 위치를 변경합니다.


여러 개발자가 기여하는 여러 iOS 앱이 있습니다. 제가 계속 알아 차리는 문제는 스토리 보드의 뷰가 배치 된 위치에서 벗어나거나 크기가 작아 지도록 크기가 조정된다는 것입니다. 텍스트에 맞게 크기가 조정 된 레이블의 경우 레이블이 모두 갑자기 텍스트가 잘립니다.

개발자가 스토리 보드를 직접 편집하지 않았을 때 Git 리포지토리에 대한 커밋에 이러한 뷰 저하가 나타납니다. 그들은 Interface Builder에서 스토리 보드를 보았을 수도 있지만 스토리 보드를 실제로 변경하지는 않았습니다. 그럼에도 불구하고 변경 사항은 저장되고 작업중인 내용과 함께 커밋되었습니다.

책임있는 커밋 전후에 스토리 보드 파일간에 텍스트를 비교하면 다음과 같은 뷰 프레임이 약간 변경됩니다.

<rect key="frame" x="203" y="8" width="362" height="29"/>
                             |
                             V
<rect key="frame" x="203" y="7.5" width="362" height="29"/>

<rect key="frame" x="446.00000170260091" y="7" width="302" height="30"/>
                      |
                      V
<rect key="frame" x="446" y="7" width="302" height="30"/>

<rect key="frame" x="364" y="3" width="200" height="38"/>
                      |
                      V
<rect key="frame" x="363" y="3" width="200" height="38"/>

<rect key="frame" x="284" y="7" width="97" height="30"/>
                      |                |
                      V                V
<rect key="frame" x="283" y="7" width="96" height="30"/>

<rect key="frame" x="384.00001078580522" y="7" width="101" height="30"/>
                      |                                |
                      V                                V
<rect key="frame" x="383.00000530853856" y="7" width="100" height="30"/>

대부분의 경우 프레임 치수의 숫자는 약간만 변경되고 정수 값이 1만큼 변경되거나 부동 소수점 값이 잘 리거나 소수 부분이 약간 변경됩니다.

다른 경우에는 다음과 같이 값이 몇 점씩 변경됩니다.

<rect key="frame" x="334" y="3" width="200" height="38"/>
                      |
                      V
<rect key="frame" x="331" y="3" width="200" height="38"/>

<rect key="frame" x="251" y="7" width="223" height="30"/>
                                        |
                                        V
<rect key="frame" x="251" y="7" width="220" height="30"/>

<rect key="frame" x="478" y="3" width="274" height="38"/>
                      |                 |
                      V                 V
<rect key="frame" x="475" y="3" width="276" height="38"/>

이러한 모든 예제 프레임 변경 사항은 개발자가 스토리 보드를 한 번만 변경하지 않았을 때 동일한 예제 커밋에서 가져온 것입니다. 파일의 두 버전 간에는 XML에 269 개의 ​​차이가 있었는데, 모두 프레임 크기 나 위치가 약간 변경되었습니다. 스토리 보드 XML은 ~ 9000 줄입니다.

이 문제는 IB의 부동 소수점 숫자 사용 및 반올림 오류와 관련이있을 수 있으며 몇 픽셀 차이로 인해 여러 번 열기, 구문 분석 및 재 직렬화하는 동안 이러한 반올림 오류가 집계 될 수 있습니다. 자료.

원치 않는 변화의 정확한 원인을 정확히 찾아 낼 수 없었기 때문에 이것은 단지 이론 일뿐입니다. 종종 커밋은 프레임을 전혀 변경하지 않고 446.00000055262581-> 446.00000112002783과 같이 사소한 부동 소수점 변경 만 수행합니다. 그러나 심각한 변화가 발생하면 많은 수의 변화가 일어나는 것 같습니다.

The commits between which the changes occur are also made by the same developer using the same version of Xcode and Interface Builder too. In this example commit where this data was taken, the document tag is <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="JAD-vj-VfC"> in both versions of the storyboard file for example.

Other than being sure to check not to commit insignificant or unintended changes to storyboard files, I'd like to narrow down what is causing these unwanted changes to our storyboard views. If it's something we can avoid doing that is causing the issue, we can be aware of the cause.

Update: As Tim helpfully noted, this issue does seem to be caused while using Interface Builder on a retina display. All the developers that have caused the problem have retina MacBook Pros. Those of us without retina displays have not experienced the issue.


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. Steps 1. 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.

참고URL : https://stackoverflow.com/questions/26598115/interface-builder-degrades-storyboards-resizes-and-repositions-views-in-small-i

반응형