And*_*rea 6 objective-c uitableview ios uicontainerview
我正在尝试找到这种情况的解决方法:
我有一个UITabBarController它的一个segue连接到一个容器视图控制器(BannerViewController),我用来嵌入一个UINavigationController,导航控制器推送其他容器视图控制器(EventListContainerviewController) )每个都包含一个tableview控制器.
这是我的故事板上的一个屏幕

问题是最后一个容器视图显示在一个比它们的容器更小的框架中.它们似乎松动了底部的tabbar空间.
我强制所有视图控制器,导航控制器和tabbar控制器都避免不扩展边缘并调整插入.
颜色意味着:
红色:BannerContainerViewController的主视图0x7fcc6d38bb00
浅绿色:BannerContainerViewController 的容器视图0x7fcc6d38b860蓝色:EventListContainerViewController的主视图0x7fcc6bd7b7c0
橙色: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, 0}; contentSize: {320, 406}>
| | | | | | | | | | | | | <EventCell: 0x7fcc6bca2950; baseClass = UITableViewCell; frame = (0 85; 320 85); autoresize = W; layer = <CALayer: 0x7fcc6bca2ca0>>
Run Code Online (Sandbox Code Playgroud)
我试图使用自定义segue而不是容器视图尝试强制布局,但我猜是导航控制器故障.
如您所见,横幅未按预期与视图重叠.
有什么建议吗?
小智 10
这个问题在iOS 10中仍然存在.嵌入在容器视图中的UINavigationController又包含在UITabBarController中,它将在导航堆栈中布置所有视图,并为底部的"幻像"选项卡栏留出额外空间.
最简单的解决方案是继承UINavigationController并从中返回'nil' tabBarController.
class MyNavigationController: UINavigationController {
override var tabBarController: UITabBarController? {
return nil
}
}
Run Code Online (Sandbox Code Playgroud)
这使得导航堆栈中的视图认为它们没有标签栏控制器,因此在布局期间它们不会为它留下额外的空间.我没有发现此修复有任何负面影响,但显然此导航控制器堆栈中的视图将无法再访问标签栏控制器.如果这是一个问题,您可以使用更通用的方法来查找标签栏控制器(或任何"父"视图控制器).
例如,如果您的应用程序的主视图控制器是名为"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
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为标签栏控制器是parent其直接子视图控制器.上述方法沿着父链,呈现和导航控制器的方式向上移动,最终到达标签栏控制器的子节点,该控制器返回标签栏控制器作为其父节点.
原来这是一个 UIKit 错误,我已经提交了一个雷达 19996374。这是解释:
当导航控制器放置在标签栏控制器内时,布局内容(您的)视图控制器的责任完全交给导航控制器。标签栏控制器调整导航控制器视图的大小以匹配标签栏控制器的视图边界。反过来,在布局内容视图控制器时,导航控制器会考虑标签栏的高度。当您在选项卡栏控制器和导航控制器之间注入视图控制器时,事情就会中断。标签栏控制器看到 selectedViewController 不是 UINavigationController 并应用正常的布局规则。但是包含的导航控制器看到它的 tabBarController 属性包含一个有效的 UITabBarController 实例,并假设它仍然负责在布局内容(您的)视图控制器时处理标签栏高度。结果是内容视图控制器被标签栏高度插入了两次,正如您所观察到的
作为一种解决方法
您可以通过将选项卡栏的 isTranslucent 属性设置为 YES 来解决此问题。然后,在 AFBannerViewController 中,覆盖 -edgesForExtendedLayout 以返回 UIRectEdgeAll。AFBannerViewController 现在将覆盖选项卡栏(因此将背景颜色设置为粉红色以外的颜色),但导航控制器会将正确的插图应用到内容视图控制器。
| 归档时间: |
|
| 查看次数: |
2833 次 |
| 最近记录: |