UIToolbar 的存在影响视图控制器视图的布局

Posted

技术标签:

【中文标题】UIToolbar 的存在影响视图控制器视图的布局【英文标题】:Presence of UIToolbar affecting layout of view controller's view 【发布时间】:2013-09-12 17:28:00 【问题描述】:

我有一个 UIPageViewController 子类,它一次显示 1 个视图控制器。显示的视图控制器有一个滚动视图。这允许用户向左/向右滚动以转到新页面,或向上向下滚动以查看大于屏幕高度的内容。 UIPageViewController 子类嵌入在 UINavigationController 中,并且 navBar 的工具栏是可见的。

可以从我的应用程序的两个不同部分访问此 UIPageViewController 子类。

在我的第一个 viewController 中,工具栏隐藏。点击这个视图控制器中的一个元素会加载 UIPageViewController,一切看起来都很好。

在我的第二个 viewController 中,工具栏是可见。点击这个视图控制器中的一个元素会加载 UIPageViewController,但是我的内容(pageViewController 的 viewController)被从导航栏向下推了一点。不过,只要我与 scrollView 交互,视图就会自动调整为正确地位于导航栏的正下方。

我在 ios7 上运行它,但我不确定这是否有任何关系。

为什么当我的视图控制器来自应用程序的两个不同部分时加载不同,一个显示工具栏,一个隐藏工具栏?

【问题讨论】:

Storyboard 中的“UIPageViewController”如何布置视图似乎是一个错误。据我所知,pageController.view 和各个视图控制器的框架位置都在 (0,0),并且尺寸宽度/高度与设备框架相匹配。 有趣。听起来我们遇到了类似的问题,但我没有使用 Storyboards。 【参考方案1】:

如果您的应用在 iOS6 上运行良好,但在 iOS7 上运行良好,请尝试将 NO 设置为 UIPageViewController(UIPVC) 的 automaticallyAdjustsScrollViewInsets 属性。

UIPVC 内部似乎有一个滚动视图。在 iOS7 上,UIViewController 的 automaticAdjustsScrollViewInsets 属性默认设置为 YES。我认为如果嵌入到 UINavigationController 中效果不好。

就我而言,我创建了自定义 UIPVC 并将以下代码放在 [viewDidLoad] 方法中。

self.automaticallyAdjustsScrollViewInsets = NO;

【讨论】:

哇!我本可以发誓我试过了,但它对我不起作用,但现在效果很好!也许我在早期的 ios7 测试版中尝试过,现在它已在 GM 中修复。无论如何,比我采取的更清洁的解决方案。 我发现这个“automaticallyAdjustsScrollViewInsets”标志只会造成麻烦。通常我会假设我使用不正确,但无论我如何使用它,行为都是不一致的,所以我现在总是将它设置为“NO”。【参考方案2】:

我终于能够在 NavController 中正确对齐嵌入式 UIPageViewController,它本身位于 TabBarcontroller 中。我通过在一个虚拟的“rootviewcontroller”中以编程方式创建 pageViewController 来做到这一点,遵循默认 Xcode“新项目”中给出的示例,称为“基于页面的应用程序”。

在我的例子中,以下情节提要布局产生错误:TabBarController -> NavController -> UIPageViewController (scroll-horizo​​ntal) -> ContentViewController

我将故事板布局更改为:TabBarController -> NavController -> CustomRootViewController

CustomRootViewController 实例化一个 UIPageViewController 并将其保存为成员属性。 CustomRootViewController 成为其 PageViewController 的 DataSource 和 Delegate。按照名为“Page-based Application”的默认 Xcode“New Project”来获取如何设置 RootViewController 的示例。

不幸的是,当您使用拖放式“UIPageViewController”时,这整个问题似乎是由 Storyboard 中的一个错误引起的,它具有滚动水平过渡类型,嵌入在 navController(和/或 tabbarcontroller)中。仅供参考 - 在 pageViewController 的 viewWillAppear 中,我尝试将 pageViewController 和 contentViewControllers 的框架分别重置为 (0,0),大小与设备匹配,但是 pageViewController 的初始 viewController 的视图总是会向下移动,看起来像是嵌入它的 tabbarcontroller 的高度。对于那些希望进一步研究这个问题的人,以下是一些观察:

    在viewDidLoad中,可以设置pageViewController初始视图的Frame来抵消layout-error。但是,您可能必须为不同方向的不同设备处理不同的布局校正,这可能会让人头疼。

    在 Storyboard 中,将 pageViewController 的过渡样式设置为“page curl”可以解决布局问题。因此,我确信布局问题存在于页面滚动中,它是在实例化时设置的。 Storyboard 的实例化会产生布局错误,但在我的 CustomRootViewController 中以编程方式实例化是没有错误的。

【讨论】:

不错的建议。奇怪的是,我在开发早期就遇到了这个问题,而且我有你建议的 VC 层次结构(没有标签栏控制器)。我的解决方法是从 rootVC 中删除 PageVC 并直接将 PageVC 子类化。现在,几周后我遇到了同样的问题,所以我想知道当时(ios7 betas)和现在(ios7 gm)之间是否发生了变化。我一定会试一试的。 这肯定是一个错误。 Apple Doc 说 PageViewController 不能嵌入到其他控件中,因此就我们对 PVC 的使用而言,我们处于不受支持的领域。重要 - 我上面的建议对 IOS6 没有好处,由于滚动视图约束的一些自动释放问题,应用程序将崩溃。我已经放弃使用嵌入在 TBC 和 NC 中的 PVC,并回到简单地将 scrollView 嵌入到 viewController 中。轻松 10 倍。恕我直言,PVC 仅在您不嵌入时才有用。 我已经阅读了 UIPVC 的类文档,并没有看到任何与将其嵌入其他控制器相关的警告。可以发个链接吗?我的应用程序有几个部分需要分页(全屏和 tableviewcell),我发现使用 PVC 容易得多,因为它可以处理出列和缓存等等。我想通过在 UIScrollView 之上构建自己的来避免这种情况 抱歉,我认为我在 PVC 必须是初始视图控制器时说错了。我正在考虑苹果文档的这一部分“使用情节提要创建页面视图控制器界面”第 4 步:developer.apple.com/library/ios/documentation/WindowsViews/… 根据我的个人经验和我看到的苹果示例,在我看来,PVC 意味着用作初始视图控制器,但到目前为止,我还无法解决嵌入 NC 和 TBC 时出现的布局/约束错误。

以上是关于UIToolbar 的存在影响视图控制器视图的布局的主要内容,如果未能解决你的问题,请参考以下文章

弹出视图后出现错误的 UIToolbar

回到我的视图控制器时,为啥我的 iPhone UIToolBar 这么大?

UITabbarController + UINavigationController,使用 UIToolbar 代替标签栏的详细视图

UIToolbar 推送视图问题

无法将项目添加到 UIToolbar

iOS UIToolBar的使用