web-dev-qa-db-ja.com

iOS7-ステータスバーの下に表示-edgeForExtendedLayoutが機能しない

昨年作成したプロジェクトがあり、ストーリーボードではなくXIBを使用しています。 XIBは自動レイアウトを使用しませんが、いくつかの自動サイズ設定を使用します。 iOS7で実行すると、すべてのビューがステータスバーの下に隠れてしまうという問題があります。これはiOS7の新機能であることを十分に理解しています。ただし、これを行わないように修正するためのすべての解決策が機能していません。ビューの上部に常にステータスバーの下に表示される画像があり、ナビゲーションバーなどを使用していません。

XIBのYデルタを更新しようとしました(ビューに影響はありません)。edgesForExtendedLayoutUIRectEdgeNone(何もしない)に設定しようとしました。 。ステータスバーは常に、ビューがその下に隠れている状態で表示されます。これは、私が何をしようとも関係ありません。つまり、ステータスバーのスペースを確保するためにXIBでビューを手動で下に移動しない限りです(ただし、このソリューションは機能しないため、機能しません。もちろん、iOS6では正しく表示されません)。

奇妙なのは、ビューシフトでハッキングするコード行を試しても、機能しないことです(次のように)。

self.view.frame = CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y+20, self.view.frame.size.width, self.view.frame.size.height);

..そのような解決策で行くわけではありませんが、うまくいかなかったのは奇妙です(通常、うまくいかないことがわかっているのは、自動レイアウトが設定されている場合で、この場合はそうではありません)。

ステータスバーが表示するのは設計上の要件であり、iOS7のステータスバーの下にビューを設定できないのはなぜですか。この件に関するすべてのスタックオーバーフローの投稿と、Appleの移行/ガイドを読みました。繰り返しになりますが、私はそれがどのように機能し、これに対する期待される解決策がどのようになるべきかを完全に理解していますが、この特定のプロジェクトではうまくいっていないようです。

私は経験豊富なiOS開発者ですが、このプロジェクトは別のチームによって構築されたため、XIBファイル、plist、またはコードのどこかに上記の設定を誤って隠しているものがあるかどうかわかりません。この点について他に確認できる点があるかどうか、または提供できる情報があるかどうかをお知らせください。

前もって感謝します!

20
svguerin3

Interface BuilderでiOS 6/7デルタ値を設定する場合は、複製するiOS 6レイアウトであるため、Interface Builder Documentで「View as」を「iOS 6」に設定してください。デルタはiOS 7でのみ使用され、ステータスバーの下にコンテンツをプッシュします。 [表示]をiOS 7(デフォルト)に設定したままにすると、デルタは代わりにiOS 7の外観をiOS 6で提供します。

ただし、フレームはデルタを考慮しないため、ビューフレームに基づいてプログラムでビューの位置やサイズを変更する場合、デルタは役に立ちません。

デルタを使用する代わりに、私が見つけた最良の解決策は、メインXIBで自動レイアウトを有効にし、トップ/コンテンツビューでトップスペース制約を設定して、トップレイアウトガイドに従うことです。このガイドはiOS 7で導入され、ステータスバーの下の位置を表しています。残念ながら、ストーリーボードを使用していない場合、ガイドはInterface Builderで利用できませんが、プログラムで追加できます。

私が行ったのは、Interface Builderの代わりにスーパービューにトップスペース制約を追加し、コードのアウトレットを作成することでした。次に、viewDidLoadで、topLayoutGuideが使用可能な場合(iOS 7以降)、このアウトレットの制約を、代わりにトップレイアウトガイドを使用するバージョンに置き換えます。

if ([self respondsToSelector:@selector(topLayoutGuide)]) {
    [self.view removeConstraint:self.containerTopSpaceConstraint];

    self.containerTopSpaceConstraint =
    [NSLayoutConstraint constraintWithItem:self.contentView
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.topLayoutGuide
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1
                                  constant:0];

    [self.view addConstraint:self.containerTopSpaceConstraint];

    [self.view setNeedsUpdateConstraints];
    [self.view layoutIfNeeded];
}
17
Kim André Sand

参考までに、以下のソリューションは、ViewControllersに適用したときに機能しました。ただし、これは理想的ではなく、少しハックです。それが私が取ることのできる唯一のアプローチであるなら、それでもそうです。

float systemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(systemVersion>=7.0f)
{
    CGRect tempRect;
    for(UIView *sub in [[self view] subviews])
    {
        tempRect = [sub frame];
        tempRect.Origin.y += 20.0f; //Height of status bar
        [sub setFrame:tempRect];
    }
}
6
svguerin3

Appleはこれを達成するためにautolayoutを使用するようにあなたに要求しています。ビューのトップサブビューから「トップレイアウトガイド」に制約を設定する必要があります。

例については、このドキュメントを参照してください。

https://developer.Apple.com/library/ios/qa/qa1797/_index.html

XIBなしでこれを行うには、プログラムで制約を追加する必要があります。 Appleのドキュメントは、この良い例を示しています。

topLayoutGuideがビューコントローラーのプロパティであるとすると、変数バインディングのディクショナリでそれを使用するだけです。次に、通常のように制約を設定します。

id topGuide = [myViewController topLayoutGuide];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button, topGuide);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]" options:0 metrics:nil views:viewsDictionary]; 

このドキュメントは UIViewControllerクラス参照 にあります。

5
petehare

1)不透明なナビゲーションバーが必要ない場合の最も簡単な解決策:

self.navigationController.navigationBar.translucent = NO;

2)svguerin3の答えは一般的なケースでは機能しません。たとえば、サブビューの1つが自動サイズ設定を使用してコンテナの下部にフックされている場合、新しい位置は正しくありません。そして、最悪の場合、画面の外に出る可能性があります。

3
Aurelien Porte
- (void)viewDidAppear:(BOOL)animated {
        [self.view setFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height)];
// OR
        self.view.transform = CGAffineTransformMakeTranslation(0, 20);
}
2
Mazen Kasser

ストーリーボードを使用している場合は、ビューの上部レイアウトを設定した後、属性インスペクターで「不透明バーの下」のチェックを外すことができます

Storyboard

0
dhin

XIBをソースとして表示し、edgesforextendedlayoutを含む行を削除してみましたか?

ストーリーボードのシーンのメインビューはXIBで表されるため、ストーリーボードのシーンでこの行を削除する必要がありました。

私たちに起こっていたのは、何とかして、いくつかのシーンでは、シーンのメインビューのXIBコンテンツがステータスバーとナビゲーションバーの高さによって押し下げられていたということです。

その行を削除すると、XIBがストーリーボードのシーンの同じトップから発生したかのように表示されます。

悲しいことに、何が原因であるかはわかりませんが、XIBのメインビュー内のコンテンツの順序を変更して、UITextViewが最初に表示されるようにすると発生します。これがトリガーされた後にアイテムの順序を並べ替えても、この不要な動作は削除されませんでした。

これがこのタイプの問題に遭遇している他の人を助けることを願っています。

0
Alex Zavatone