70

UIPageViewController透明のステータス バーとナビゲーション バーがあります。topLayoutGuide予想通り、64ピクセルです。

ただし、ステータス バーとナビゲーション バーの下に表示されている場合でも、UIPageViewControllerレポートの子ビュー コントローラーは0 ピクセルです。topLayoutGuide

これは予想される動作ですか?もしそうなら、実際の下に子View Controllerのビューを配置する最良の方法は何topLayoutGuideですか?

parentViewController.topLayoutGuide私はハックと考える を使用することを除いて)

4

11 に答える 11

49

この答えは正しいかもしれませんが、包含ツリーを上に移動して正しい親View Controllerを見つけ、あなたが「本当のtopLayoutGuide」と表現するものを取得する必要があることに気付きました。このようにして、手動で実装できますautomaticallyAdjustsScrollViewInsets

これが私がやっている方法です:

私のテーブルビューコントローラー(UIViewController実際にはサブクラス)には、これがあります:

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    _tableView.frame = self.view.bounds;

    const UIEdgeInsets insets = (self.automaticallyAdjustsScrollViewInsets) ? UIEdgeInsetsMake(self.ms_navigationBarTopLayoutGuide.length,
                                                                                               0.0,
                                                                                               self.ms_navigationBarBottomLayoutGuide.length,
                                                                                               0.0) : UIEdgeInsetsZero;
    _tableView.contentInset = _tableView.scrollIndicatorInsets = insets;
}

のカテゴリ メソッドに注目してくださいUIViewController。これが私が実装した方法です。

@implementation UIViewController (MSLayoutSupport)

- (id<UILayoutSupport>)ms_navigationBarTopLayoutGuide {
    if (self.parentViewController &&
        ![self.parentViewController isKindOfClass:UINavigationController.class]) {
        return self.parentViewController.ms_navigationBarTopLayoutGuide;
    } else {
        return self.topLayoutGuide;
    }
}

- (id<UILayoutSupport>)ms_navigationBarBottomLayoutGuide {
    if (self.parentViewController &&
        ![self.parentViewController isKindOfClass:UINavigationController.class]) {
        return self.parentViewController.ms_navigationBarBottomLayoutGuide;
    } else {
        return self.bottomLayoutGuide;
    }
}

@end

お役に立てれば :)

于 2014-02-04T01:48:12.157 に答える
11

私は間違っているかもしれませんが、私の意見では、動作は正しいです。topLayout 値は、コンテナー ビュー コントローラーで使用して、そのビューのサブビューをレイアウトできます。

リファレンスには次のように書かれています。

制約を使用せずにトップ レイアウト ガイドを使用するには、含まれているビューの上境界に対するガイドの位置を取得します。

親では、それを含むビューに対して、値は 64 になります。

子では、含まれているビュー (親) に対して、値は 0 になります。

コンテナー View Controller では、次のようにプロパティを使用できます。

- (void) viewWillLayoutSubviews {

    CGRect viewBounds = self.view.bounds;
    CGFloat topBarOffset = self.topLayoutGuide.length;

    for (UIView *view in [self.view subviews]){
        view.frame = CGRectMake(viewBounds.origin.x, viewBounds.origin.y+topBarOffset, viewBounds.size.width, viewBounds.size.height-topBarOffset);
    }
}

子ビュー コントローラーは、ナビゲーションとステータス バーがあることを知る必要はありません。その親は、それを考慮してサブビューを既にレイアウトしています。

新しいページ ベースのプロジェクトを作成し、それをナビゲーション コントローラーに埋め込み、このコードを親ビュー コントローラーに追加すると、正常に動作しているように見えます。

ここに画像の説明を入力

于 2013-10-11T12:00:31.783 に答える
11

ストーリーボードに制約を追加し、viewWillLayoutSubviews で変更できます

このようなもの:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    self.topGuideConstraint.constant = [self.parentViewController.topLayoutGuide length];
}
于 2014-03-06T09:19:56.933 に答える
3

UIPageViewControllerOPのようなものがあり、たとえばコレクションView Controllerを子として持っている場合。コンテンツ インセットの修正は簡単で、iOS 8 で動作することがわかりました。

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    UIEdgeInsets insets = self.collectionView.contentInset;
    insets.top = self.parentViewController.topLayoutGuide.length;
    self.collectionView.contentInset = insets;
    self.collectionView.scrollIndicatorInsets = insets;
}
于 2014-12-15T17:03:04.673 に答える
2

これは iOS 8 で対処されています。

子View ControllerのtopLayoutGuide位置を設定する方法

(top|bottom|left|right)LayoutGuide基本的に、コンテナー ビュー コントローラーは、他のビューと同様に、子ビュー コントローラーを制約する必要があります。(iOS 7 では、必要な優先順位で既に完全に制約されているため、これは機能しませんでした。)

于 2014-07-21T18:54:52.557 に答える
0

これは既知のガイド長に対するアプローチです。ガイドではなく、ガイド距離を想定した固定定数でビューの上部に制約を作成します。

于 2014-12-17T22:43:18.270 に答える
0

私がまだ数分前にやったように、誰かがまだこれに問題があるかどうかはわかりません.
私の問題は次のようなものです( https://knuspermagier.de/2014-fixing-uipageviewcontrollers-top-layout-guide-problems.htmlからのソースgif )。
要するに、私の pageViewController には 3 つの子ビューコントローラーがあります。最初のビューコントローラーは問題ありませんが、次のビューコントローラーにスライドすると、ビュー全体が誤って上部にオフセットされますが (~20 ピクセルだと思います)、指が画面から離れた後は通常に戻ります。
私はこれに対する解決策を探して一晩中起きていましたが、それでも解決策を見つけることができませんでした. そして突然、私はこのクレイジーなアイデアを思いつきました:

[pageViewController setViewControllers:@[listViewControllers[1]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) {

}];

[pageViewController setViewControllers:@[listViewControllers[0]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished) {

}];

私のlistViewControllersには3つの子ビューコントローラーがあります。インデックス 0 に問題があるため、最初に pageviewcontroller のルートとして設定し、その直後に最初のビュー コントローラーに戻します (予想どおり)。出来上がり、うまくいきました!
それが役に立てば幸い!

于 2015-11-14T03:10:24.063 に答える