iOS 7:自定义容器视图控制器和内容插入

taj*_*hal 24 objective-c uiviewcontroller ios ios7

我有一个包含在导航控制器中的表视图控制器.导航控制器似乎在通过表格视图控制器呈现时自动将正确的内容插入应用于表视图控制器presentViewController:animated:completion:.(任何人都可以向我解释这是如何工作的吗?)

但是,只要我将组合包装在自定义容器视图控制器中并显示该组合,表视图内容的最顶部就会隐藏在导航栏后面.为了在此配置中保留自动内容插入行为,我能做些什么吗?我是否必须在容器视图控制器中"通过"某些内容才能使其正常工作?

我想避免手动或通过自动布局调整内容,因为我想继续支持iOS 5.

Joh*_*rug 12

我有类似的问题.所以在iOS 7上,有一个新的属性UIViewController被调用automaticallyAdjustsScrollViewInsets.默认情况下,此设置为YES.当您的视图层次结构比导航或标签栏控制器内的滚动/表格视图更复杂时,此属性似乎对我不起作用.

我做的是这样的:我创建了一个基本视图控制器类,我的所有其他视图控制器都继承自.该视图控制器然后负责显式设置insets:

标题:

#import <UIKit/UIKit.h>

@interface SPWKBaseCollectionViewController : UICollectionViewController

@end
Run Code Online (Sandbox Code Playgroud)

执行:

#import "SPWKBaseCollectionViewController.h"

@implementation SPWKBaseCollectionViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    [self updateContentInsetsForInterfaceOrientation:self.interfaceOrientation];
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self updateContentInsetsForInterfaceOrientation:toInterfaceOrientation];

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)updateContentInsetsForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        UIEdgeInsets insets;

        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            insets = UIEdgeInsetsMake(64, 0, 56, 0);
        } else if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            if (UIInterfaceOrientationIsPortrait(orientation)) {
                insets = UIEdgeInsetsMake(64, 0, 49, 0);
            } else {
                insets = UIEdgeInsetsMake(52, 0, 49, 0);
            }
        }

        self.collectionView.contentInset = insets;
        self.collectionView.scrollIndicatorInsets = insets;
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

这也适用于Web视图:

self.webView.scrollView.contentInset = insets;
self.webView.scrollView.scrollIndicatorInsets = insets;
Run Code Online (Sandbox Code Playgroud)

如果有更优雅,更可靠的方法,请告诉我!硬编码的插入值非常糟糕,但是当你想要保持iOS 5兼容性时,我并没有真正看到另一种方式.


BFa*_*Far 5

仅供参考,以防任何人遇到类似问题:automaticallyAdjustsScrollViewInsets只有当您的滚动视图(或tableview/collectionview/webview)是其视图控制器层次结构中的第一个视图时,才会应用它.

我经常在我的层次结构中添加一个UIImageView以获得背景图像.如果这样做,则必须在viewDidLayoutSubviews中手动设置scrollview的边缘插入:

- (void) viewDidLayoutSubviews {
    CGFloat top = self.topLayoutGuide.length;
    CGFloat bottom = self.bottomLayoutGuide.length;
    UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
    self.collectionView.contentInset = newInsets;

}
Run Code Online (Sandbox Code Playgroud)


taj*_*hal 4

感谢 Johannes Fahrenkrug 的提示,我弄清楚了以下内容:automaticallyAdjustsScrollViewInsets确实,只有当子视图控制器的根视图是UIScrollView. 对我来说,这意味着以下安排有效:

自定义容器视图控制器内的导航控制器内的内容视图控制器。

虽然这不会:

导航控制器内的自定义容器视图控制器内的内容视图控制器。

然而,从逻辑角度来看,第二种选择似乎更明智。第一个选项可能仅有效,因为自定义容器视图控制器用于将视图附加到内容的底部。如果我想将视图放在导航栏和内容之间,则不会那样工作。