web-dev-qa-db-ja.com

Interface Builder:UIViewのレイアウトiOS 6/7デルタは何のためですか?

UIViewのstructsレイアウトの下にiOS 6/7 Deltaプロパティが見つかりました。

これは何のためであり、なぜこれがAutoLayoutにないのですか?

enter image description here

111

これは、実際にはiOS6からiOS7までのレイアウト位置間のデルタを指します。

IOS7では、一部のビューではステータスバーを非表示にしたり、透明にしたりすることができ、実際にはビューの上部にオーバーレイされます。したがって、iOS6でUI要素を(0.0、0.0)に配置すると、ステータスバーの下に表示されますが、iOS7では、ステータスバーの下に部分的に隠れて表示されます。その場合、iOS6とiOS7でレイアウトが同じに見えるように、ステータスバーの高さ(20.0ポイント)と一致するデルタが必要になります。

自動レイアウトを使用する場合、これは必要ではないと思いますが、もちろん、iPad1のサポートは失われます。多くの人はこの時点で譲歩するつもりはありません。

83
digarok

注:しばらく前にこの質問に気づきましたが、NDAが解除されたため、回答を投稿するだけです

AutoLayoutで表示されないのはなぜですか?

お気づきかもしれませんが、iOS 7はまったく新しい外観をもたらします。 UI要素の外観は変更されましたが、サイズの一部(または一般的なメトリック)も変更されました。これにより、iOS 7とその前身の両方に対応するインターフェイス設計が可能になります。

Appleの公式の方針は、これを解決するためにAutoLayoutを使用することです。これにより、UI要素をレイアウトするのに手間がかかります。特にビジネス上の理由でiOS 5をサポートする必要がある場合、またはAutoLayoutの実装を困難にする方法でインターフェイスが管理されている場合は特に、これを組み込むことは簡単ではありません。このように、Appleは、このニッチなカテゴリに分類された場合に仕事を少し楽にする方法を提供しているようで、彼らはこのiOS 6/7デルタと呼んでいます。

では、何をするのでしょうか?

Interface Builderのラベルは、このコンテキストで「Delta」が何を意味するかについては少し不明確ですが、この機能に対応する.xibファイルに含まれるコードはもう少し明確です。

<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>

キー名insetFor6xAndEarlierは、これが何をするかを明示的に示します。 iOS 7の前身で実行する場合、UI要素の代替インセットを提供できます。たとえば、上記は次のデルタ変更を定義します。

x: 50
y: 100
width: -100
height: 200

.xibに格納されている値は引用された値に直接対応していませんが、それらの間には相関関係があります。

x: -minX
y: -minY
width: minX + maxX
height: minY + maxY

以下の画像は、この変化を視覚的に示しています。これは非常に極端な例ですが、その能力を実証するためのものです。実際には、ほんの数ピクセルのデルタ変更しかないと予想されます。

iOS7 View

iOS6 View

IOS 6ビューでは値が逆になっていることに気付くかもしれません。これは、デルタが作業しているビューのタイプに関連しているためです。 iOS 6用に編集している場合、iOS 7用の要素を正しく変換するためにそこにあるデルタがあります(上記の例の逆)。

さまざまなスタイルを表示するには、実行中のOSに基づいてInterface Builderが表示する方法を変更できます。これは、ファイルインスペクター-> Interface Builder Document(右側のバーの最初のタブ)に含まれています。

Interface Style Switch

インターフェイスを手動でコーディングしたい場合、これは存在しますか?

直接ではありませんが、コード内のOSバージョンを条件付きでチェックし、それに応じて正しい位置/サイズを設定することにより、同じ効果を簡単に実現できます。 Interface Builderには、コードを使用せずに条件付き位置決めを行う簡単な方法がないため、デルタ機能があります。InterfaceBuilderのポイントは、UIで可能な限り多くのコードを取得することです。

全体...

Appleは、ほとんどの場合、AutoLayoutを使用して生活を楽にすることを強くお勧めします。使用できない場合(上記の理由により)、デルタを使用すると、現在のOSのメトリックに基づいてUI要素を適切に配置する柔軟性が得られます。コード内で手動で再配置する必要はありません。良い例は、ステータスバーの不足を調整することですが、他にも多くの使用例があります。

当然、iOS7以上でのみ開発している場合、この機能を知る必要はありません/発見する必要はありません。 iOS7 SDKでビルドしたときに、自動レイアウトなしでアプリケーションを実行するiOS6デバイスが必要な場合にのみ、デルタが必要になります。

執筆時点(8月21日)では、この機能に関するドキュメントもWWDCの資料にも記載されていません。私はあちこちで遊びましたが、少し調査した結果、それが発見されました。

108
WDUK

これは既に回答済みであり、自動レイアウトを使用せずにiOS 6.1以前のバージョンを引き続きサポートしたい人にも役立つと期待している小さなバリアントを追加するだけです。

これを読む Appleの移行ガイド-以前のバージョンをサポートする

「iOS 7.0以降」から「表示」を選択します

enter image description here

IOS 7のベースUI。iOS6の場合、適切なデルタ値を指定します。プレビューを使用して、これがiOS 7およびiOS 6デバイスでどのようにレンダリングされるかを確認します。

enter image description here

クイックステップ:

ルートビューの直接の子を個別に選択し、その「Y」値に20pxを追加します。

enter image description here

次に、すべての直接の子をまとめて選択し、デルタYを-20pxとして指定します。これをバッチで、または個別に行うこともできます。

enter image description here

30
Saran

AutoLayoutには少なくともiOS 6.0が必要です。 iOS 5.0をサポートする場合は、AutoLayoutを使用できません。

また、これらのデルタは、異なるiOSバージョン(主にiOS 7およびiOSバージョン7より前のバージョン)で表示位置を調整するために使用されます。

これらの価値を使って、この絵が好きになりました。 enter image description here

9
sunkehappy

IOS 6/7 Deltaの動作を確認するには、iOS 6とiOS 7の両方のデバイスで適切に表示されるSegmentedControlでデモを行います。

最初に、ストーリーボードで.XibまたはViewControllerを選択します。 Autolayoutを使用して、「iOS 7以降で表示」を選択解除します

enter image description here

Interface Builderキャンバスで、Origin.yが20になるようにSegmentedControlを配置します。iOS6/7 Deltaでは、DeltaYには-20を選択します

enter image description here

これにより、iOS 6およびiOS 7デバイスの両方で、SegmentedControlがステータスバーの下に配置されます。

enter image description hereenter image description here

iOS 7ステータスバーの開発者ガイド からの別の便利な引用

デルタはビューごとに個別に設定でき、期待どおりに機能します。ストーリーボードまたはペン先がiOS 6として表示するように設定されている場合、デルタを設定すると、iOS 7で実行するときに、設定されたデルタ量だけそのビューがシフトおよび/またはサイズ変更されますiOS 7では、iOS 6で実行するとデルタが適用されます

3
onmyway133

AutoLayoutを使用している場合、Deltaは使用できません。これを試してください(iOS6を実行しているiPhone 4sでテスト済み):

- (void) viewWillLayoutSubviews {

//iOS 6 workaround offset
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {

    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10);

    self.view.frame = screenFrame;
}
}
0