ios - 嵌入在容器 View 中的 UINavigationController,显示大小错误的 TableView Controller

标签 ios objective-c uitableview uicontainerview

我正试图找到解决这种情况的方法:
我有一个 UITabBarController,其中一个 segue 连接到我用来嵌入 UINavigationController 的容器 View Controller (BannerViewController),导航 Controller 推送其他容器 View Controller (EventListContainerviewController),每个 Controller 都包含一个 TableView Controller 。
这是我 Storyboard上的屏幕 enter image description here
问题是最后一个容器 View 显示在比它们的容器更小的框架中。似乎他们松开了底部的标签栏空间。 enter image description here
我已经强制所有 View Controller 、导航 Controller 和标签栏 Controller 避免不扩展它们的边缘和调整插图。

颜色表示:

Red: main view of the BannerContainerViewController 0x7fcc6d38bb00
light green : the container view of the BannerContainerViewController 0x7fcc6d38b860

Blue: main view of the EventListContainerViewController 0x7fcc6bd7b7c0
Orange: the container view of the EventListContainerViewController 0x7fcc6bd7b690

当导航 Controller 添加蓝色容器 View 时,它的大小减少了相同数量的标签栏 (49pt),似乎有些事情发生了变化。 在 View 层级的递归描述中也可以看出:

<UIWindow: 0x7fcc6bd5af40; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7fcc6bd4dd80>; layer = <UIWindowLayer: 0x7fcc6bd317c0>>
   | <UILayoutContainerView: 0x7fcc6bd671c0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7fcc6bd66de0>>
   |    | <UITransitionView: 0x7fcc6bd6a980; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7fcc6bd6ace0>>
   |    |    | <UIViewControllerWrapperView: 0x7fcc6d3a7b20; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7fcc6d3a7db0>>
   |    |    |    | <UIView: 0x7fcc6d38bb00; frame = (0 0; 320 519); autoresize = W+H; layer = <CALayer: 0x7fcc6d38bbd0>>
   |    |    |    |    | <UIView: 0x7fcc6d38b860; frame = (0 0; 320 519); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fcc6d38b930>>
   |    |    |    |    |    | <UILayoutContainerView: 0x7fcc6d398000; frame = (0 0; 320 519); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fcc6d3a4b50>; layer = <CALayer: 0x7fcc6d387670>>
   |    |    |    |    |    |    | <UINavigationTransitionView: 0x7fcc6d39cfa0; frame = (0 0; 320 519); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7fcc6d39cc40>>
   |    |    |    |    |    |    |    | <UIViewControllerWrapperView: 0x7fcc6bf31230; frame = (0 0; 320 519); autoresize = W+H; layer = <CALayer: 0x7fcc6bf31300>>
   |    |    |    |    |    |    |    |    | <UIView: 0x7fcc6bd7b7c0; frame = (0 64; 320 406); autoresize = W+H; layer = <CALayer: 0x7fcc6bd7afe0>>
   |    |    |    |    |    |    |    |    |    | <UIView: 0x7fcc6bd7b690; frame = (0 0; 320 406); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fcc6bd7aac0>>
   |    |    |    |    |    |    |    |    |    |    | <UITableView: 0x7fcc6f03c400; frame = (0 0; 320 406); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fcc6bf34aa0>; layer = <CALayer: 0x7fcc6bf30bc0>; contentOffset: {0, 0}; contentSize: {320, 170}>
   |    |    |    |    |    |    |    |    |    |    |    | <UITableViewWrapperView: 0x7fcc6bf35960; frame = (0 0; 320 406); gestureRecognizers = <NSArray: 0x7fcc6bf363e0>; layer = <CALayer: 0x7fcc6bf35ed0>; contentOffset: {0, 0}; contentSize: {320, 406}>
   |    |    |    |    |    |    |    |    |    |    |    |    | <EventCell: 0x7fcc6bca2950; baseClass = UITableViewCell; frame = (0 85; 320 85); autoresize = W; layer = <CALayer: 0x7fcc6bca2ca0>>

我尝试使用自定义 segue 而不是容器 View 来尝试强制布局,但我猜是导航 Controller 故障。
如您所见,横幅没有按预期与 View 重叠。
enter image description here

有什么建议吗?

最佳答案

此问题在 iOS 10 中仍然存在。嵌入容器 View 中的 UINavigationController 又包含在 UITabBarController 中,将在导航堆栈中布置所有 View ,并在底部为“幻影”选项卡栏留出额外空间.

最简单的解决方案是继承 UINavigationController 并从 tabBarController 返回“nil”。

class MyNavigationController: UINavigationController {

    override var tabBarController: UITabBarController? {
        return nil
    }

}

这使得导航堆栈中的 View 认为它们没有标签栏 Controller ,因此它们不会在布局期间为其留出额外空间。我没有注意到此修复有任何负面影响,但显然此导航 Controller 堆栈中的 View 将无法再访问选项卡栏 Controller 。如果这是一个问题,您可以使用更通用的方法来查找选项卡栏 Controller (或任何“父” View Controller )。

例如,如果您应用的主视图 Controller 是一个名为“MainViewController”的 UITabBarController,您可以使用一种方便的方法扩展 UIViewController 以找到它。

extension UIViewController {

    func mainViewController() -> MainViewController? {
        var vc: UIViewController? = self
        while !(vc is MainViewController) && vc != nil {
            vc = vc?.parent ?? vc?.navigationController ?? vc?.presentingViewController
        }
        return vc as? MainViewController
    }

}

之所以可行,是因为选项卡栏 Controller 是其直接 subview Controller 的 parent。上述方法沿着父级、呈现和导航 Controller 链向上运行,最终到达标签栏 Controller 的子级,该子级返回标签栏 Controller 作为其父级。

关于ios - 嵌入在容器 View 中的 UINavigationController,显示大小错误的 TableView Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28608817/

相关文章:

ios - 通过 UITableVIew 中的部分快速通用基本搜索功能

objective-c - 防止将 UIButton 拖到其 UIView 之外

ios - 在 Swift 中将 UILabel 子字符串转换为 UIButton

ios - 如何检查 UIButton 是否有目标?

Iphone UITableView、单元格和通知 - 通知后单元格未显示正确的图像

ios - [NSString floatValue] 中的浮点值在打印时显示不同的结果

ios - 如何将对象转至 UITabBarController

ios - UITableViewCell 不能用一根手指点击,但可以用两根手指点击

ios - 导航 Controller 的最佳实践

ios - 通知声音不想通过硬件键关闭