ios – 嵌入在容器视图中的UINavigationController,显示大小错误的表视图控制器

前端之家收集整理的这篇文章主要介绍了ios – 嵌入在容器视图中的UINavigationController,显示大小错误的表视图控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试找到解决这种情况的方法
我有一个UITabBarController它的一个segue连接到一个容器视图控制器(BannerViewController),我用来嵌入一个UINavigationController,导航控制器推送其他容器视图控制器(EventListContainerviewController),每个包含一个tableview控制器.
这是我的故事板上的一个屏幕

问题是最后一个容器视图显示在一个比它们的容器更小的框架中.它们似乎松动了底部的tabbar空间.

我强制所有视图控制器,导航控制器和tabbar控制器都避免不扩展边缘并调整插入.

颜色意味着:

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

当导航控制器添加蓝色容器视图时,似乎某些东西会发生变化,从而减少相同数量的tabbar(49pt).
它也可以在视图层次结构的递归描述中看到:

<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,406}>
   |    |    |    |    |    |    |    |    |    |    |    |    | <EventCell: 0x7fcc6bca2950; baseClass = UITableViewCell; frame = (0 85; 320 85); autoresize = W; layer = <CALayer: 0x7fcc6bca2ca0>>

我试图使用自定义segue而不是容器视图尝试强制布局,但我猜是导航控制器故障.
如您所见,横幅未按预期与视图重叠.

有什么建议吗?

解决方法

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

最简单的解决方案是子类化UINavigationController并从tabBarController返回’nil’.

class MyNavigationController: UINavigationController {

    override var tabBarController: UITabBarController? {
        return nil
    }

}

这使得导航堆栈中的视图认为它们没有标签栏控制器,因此在布局期间它们不会为它留下额外的空间.我没有发现此修复有任何负面影响,但显然此导航控制器堆栈中的视图将无法再访问标签栏控制器.如果这是一个问题,您可以使用更通用的方法来查找标签栏控制器(或任何“父”视图控制器).

例如,如果您的应用程序的主视图控制器是名为“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
    }

}

这是因为标签栏控制器是其直接子视图控制器的父级.上述方法沿着父链,呈现和导航控制器的方式向上移动,最终到达标签栏控制器的子节点,该控制器返回标签栏控制器作为其父节点.

猜你在找的iOS相关文章