web-dev-qa-db-ja.com

Interface Builderはストーリーボードを劣化させ、ビューのサイズを変更し、少しずつ再配置します

いくつかの異なる開発者が貢献しているiOSアプリがいくつかあります。私が引き続き気付いている問題は、ストーリーボードのビューが配置された位置からシフトするか、サイズが小さくなるようにサイズ変更されることです。これは、テキストに合わせてサイズ設定されたラベルでは、すべてのラベルが突然彼らのテキストを切り捨てています。

開発者がストーリーボードを直接編集しなかった場合、ビューのこれらの低下がGitリポジトリへのコミットに表示されることに気づきました。彼らはInterfaceBuilderでストーリーボードを表示した可能性がありますが、ストーリーボードに実際の変更は加えていません。それにもかかわらず、変更は保存され、作業内容とともにコミットされました。

責任あるコミットの前後でストーリーボードファイル間でテキスト比較を行うと、次のようなフレームを表示するための小さな変更が表示されます。

<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"/>

これらのフレーム変更の例はすべて、開発者がストーリーボードに1つの変更を加えるつもりがなかった場合に、同じコミット例から取得されたことに注意してください。ファイルの2つのバージョン間でXMLに269の違いがあり、それらはすべてフレームサイズまたは位置のこれらのわずかな変更でした。ストーリーボードのXMLは約9000行です。

この問題は、IBによる浮動小数点数の使用と丸め誤差に関係しているようです。数ピクセル離れた違いは、これらの丸め誤差を数回開いて解析し、再シリアル化した期間に集約されたものである可能性があります。データ。

不要な変更の正確な原因を特定できなかったため、これは単なる理論です。多くの場合、コミットはフレームに大きな変更を加えず、446.00000055262581-> 446.00000112002783などの重要でない浮動小数点の変更のみを行います。しかし、深刻な変化が起こったとき、それらは大量に起こっているようです。

変更が発生するコミットも、同じバージョンのXcodeとInterfaceBuilderを使用して同じ開発者によって行われます。このデータが取得されたコミットの例では、ドキュメントタグは、たとえばストーリーボードファイルの両方のバージョンで<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">です。

ストーリーボードファイルに重要でない、または意図しない変更を加えないように確認する以外に、ストーリーボードビューにこれらの不要な変更を引き起こしている原因を絞り込みたいと思います。問題の原因となっているのを回避できる場合は、原因を特定できます。

pdate: Timが参考に述べたように、この問題はRetinaディスプレイでInterfaceBuilderを使用しているときに発生したようです。問題を引き起こしたすべての開発者は、Retina MacBookProを持っています。 Retinaディスプレイを持たない人は、この問題を経験していません。

68
Jeff Lockhart

この謎の中で最も興味深い手がかりは、Retinaディスプレイではなく、Retinaディスプレイで同じストーリーボードを開くと、特に悪いように見えることです。

最初、私は4kiMacとPre-retinaMacbook proの間を行き来していて、大量の変更を取得していました(毎回最大300行が変更されました)。

次に、xcodeウィンドウをメインモニター(4k/Retina)から2番目のモニター(2560x1440、非Retina)にドラッグしました。ウィンドウは同じサイズでしたが、xcodeはすべての要素のサイズを変更し、ビューの位置が50個まで間違っていると文句を言いました。 。私はそれを網膜ディスプレイに戻し、「置き忘れた」エラーの約半分は消えましたが、半分は残っていました。あなたが示唆するように、再スケーリングは基礎となるデータを劣化させます。

同じファイルで複数の開発者が作業している場合、これは頻繁に発生します。

ソリューション?これはおそらくすべてApple修正する必要があります-そうでなければそれを軽減するような設定に遭遇したことはありません。

21
Tim O'Neil

これは、InterfaceBuilderによるCGFloat値のシリアル化に関連するバグのようです。ビューフレームのサイズと位置の値は浮動小数点です。ただし、それらの値は常に整数です。内部グラフィック操作では、変換演算が機能するために浮動小数点である必要がありますが、すべては常に整数の丸めポイント値で表されます。

これらの浮動小数点値がストーリーボードXMLにシリアル化される場合、IBは値を整数としてシリアル化することがよくありますが、浮動小数点数としてシリアル化することもあります。なぜそうするのにこのようにすることを決定するのかはわかりませんが、あまり一般的ではありません。上記のフレームの例では、3つの値が浮動小数点になり、他の値は整数になりました。

私の例でも見られるように、浮動小数点表現は、代わりに整数としてシリアル化されるように変更されることがよくあります。ここでバグが見つかったと思います。

ビューフレームの変化に気付いたのは、左に移動したり、サイズが縮小したりする傾向があったことです。そのため、値はほとんど小さくなっています。私が提供した例でわかるように、これはほとんどの場合に当てはまります。

浮動小数点は整数値を正確に表現する精度はありませんが、小数点以下数桁まで正確です。したがって、私の例では、整数が整数値よりもわずかに高い値(つまり、384.00001078580522)として表現される場合もありますが、整数値よりもわずかに低いものとして表現される場合もあります。 IBが行ったフレーム変更の例を次に示します。

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

この特定の変更は、フレームの値を直接変更するようには見えませんでした。両方の数値は基本的に457に等しいです。ストーリーボードを再度開いたときにこのXMLが再解析されると、456.99999985252464の値が切り捨てられ、456として読み取られる可能性があります。これにより、値が徐々に増加します。小さく、サイズを縮小するか、フレームの位置を左または上にシフトします。

もちろん、これは単なる理論であり、InterfaceBuilderがこれを行っている理由を示すものではありません。最近のXcode6リリースから始まったようです。また、ある例では8から7.5に、最後の例では274から276になったことについても説明していません。しかし、ほとんどの場合、変更のほとんどは下向きになる傾向があります。

Appleでバグを報告して、これを調査します。

6
Jeff Lockhart

私はこの問題に対する答えがあるかもしれません。低解像度モードでアプリを開くというあまり知られていない機能です。最近、同様の問題が発生しました。区切り線がデフォルトまたは単一に設定されている場合、テーブルビューセルのコンテンツビューの高さが0.5余分になります。 Noneに設定すると、この問題は発生しませんでした。手順1.デフォルトのTVCをストーリーボードにドラッグします。テーブルビューセルのコンテンツビューの高さを確認します。 43.5になります。 2.テーブルビューの区切り線を[なし]に設定します。セルのコンテンツビューが44に変わります。

Xcodeを終了し、XcodeアプリのFinder GetInfoウィンドウでOpenin LowResolutionモードを設定します。上記と同じ手順を実行すると、テーブルビューセルのコンテンツビューの高さが43と表示されます。

Retinaディスプレイと非Retinaディスプレイで作業しているさまざまなチームメンバーがいる場合、Retinaディスプレイでストーリーボードを開いたという理由だけで、ストーリーボードファイルが変更されたままになります。この回避策の1つは、[開く]を[低解像度]モードにして動作させることです。ただし、何も変更していない場合でも、ストーリーボードを変更済みとしてマークするよりは、Retinaディスプレイを表示するという目的は無効になります。

3
Pradeep K