将视图添加为子视图时,ContentInset未更新

时间:2016-06-22 09:06:22

标签: swift uitableview layout uinavigationbar ios9

我正在制作照片浏览应用,用户可以通过该网络查看正在查看的照片的详细信息和评论。为此,我有一个带有分段控件的UIViewController(parentVC),它充当详细信息和注释之间的切换,以及两个提供详细信息和注释的UITableViewControllers。 Storyboard of the view controllers in question

要在视图之间切换,tableVC将从故事板中实例化,并作为childViewController添加到parentVC,并将其视图添加为子视图。

由于segmentedControl被放置在navigationController的navBar中,我也希望tableViews能够与parentVC的导航栏很好地配合使用。在实例化第一个tableview(detailVC)时,会自动调整其contentInset。

但是,当从分段控件切换后实例化第二个tableview(commentsVC)时,它的contentInset没有设置(实际上它对所有边都是0),并且tableview被隐藏了在navBar后面。但是当设备旋转时,tableview会调整其插图并再次正常工作。

现在我怀疑这个问题与iOS如何自动调整滚动视图设置有关,因为首先切换哪个childVC会始终设置第一个呈现的VC&contentInset。我不知道是否有任何方法可以触发它来添加第二个VC的contentInset。

所以问题是,我如何同时拥有子VC和#39; contentInset设置为尊重parentVC中的navigationBar?创建UIEdgeInset是一种变通方法,但在更改设备方向时它不会自动更新。一个更小的问题是,当childVCs以编程方式实例化时,我应该如何使用导航控制器的布局和插图,以便它们像在故事板本身中链接一样工作。

以下是从parentVC实例化childVC时的代码。

    if index == 0 { //details

        if detailsVC == nil {
            detailsVC = storyboard?.instantiateViewControllerWithIdentifier("InfoPaneDetailsVC") as! InfoPaneDetailsVC
        }
        if commentsVC != nil {
            commentsVC.view.removeFromSuperview()
            commentsVC.removeFromParentViewController()
        }

        addChildViewController(detailsVC)
        detailsVC.didMoveToParentViewController(self)
        view.addSubview(detailsVC.view)
        view.layoutSubviews()

    } else if index == 1 { //comments

        if commentsVC == nil {
            commentsVC = storyboard?.instantiateViewControllerWithIdentifier("InfoPaneCommentsVC") as! InfoPaneCommentsVC
        }
        if detailsVC != nil {
            detailsVC.view.removeFromSuperview()
            detailsVC.removeFromParentViewController()
        }

        addChildViewController(commentsVC)
        commentsVC.didMoveToParentViewController(self)
        view.addSubview(commentsVC.view)
        view.layoutSubviews()

    }

1 个答案:

答案 0 :(得分:0)

  

tableview隐藏在navBar后面。但是当设备旋转时,tableview会调整其插图   再次正常工作。

我可以复制你所看到的内容。我不知道为什么旋转设备会摆脱underlap *。我甚至可以横向启动应用程序,并且TableView将重置NavigationBar,然后当我旋转到肖像时,underlap消失。

有几种解决方案适合我:

  1. edgesForExtendedLayout = .None
  2. navigationController?.navigationBar.translucent = false
  3. 如果ViewController的父级是NavigationController(或TabBarController),那么两个属性将确定underlap如何工作:

    1. ViewController的edgesForExtendedLayout属性。
    2. NavigationBar的translucent属性。
    3. edgesForExtendedLayout属性的默认值为.All,这意味着ViewController的视图将覆盖所有半透明条。

      您可以检查您的NavigationBar是否是半透明的:

      import UIKit
      
      class InfoViewController: UIViewController {
      
           override func viewDidLoad() {
              super.viewDidLoad()
      
              if navigationController?.navigationBar.translucent == true {
                  print("NavigationBar is translucent.")
              }
      
              if edgesForExtendedLayout == .All {
                  print("This ViewController's view will underlap a translucent NavigationBar.")
              }
      

      我明白了:

      NavigationBar is translucent.
      This ViewController's view will underlap a translucent NavigationBar.
      

      UINavigationBar docs**

        

      此外, 导航栏默认为半透明 。转动   半透明关闭或打开不会影响按钮,因为它们没有   背景。

      你可以像这样阻止underlap:

      import UIKit
      
      class InfoViewController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              edgesForExtendedLayout = .None
          }
      

      .None告诉ViewController的视图不要重叠任何半透明条。或者,您可以使用.Bottom,这意味着视图将只覆盖半透明的底栏,即不是半透明的顶栏。 (要查看可分配给edgesForExtendedLayout的各种值或值的组合,请查看docs

      或者,你可以像这样阻止underlap:

      import UIKit
      
      class InfoViewController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              navigationController?.navigationBar.translucent = false
          }
      

      edgesForExtendedLayout的值仅适用于半透明条形图 - 视图不会覆盖不透明条形图。如果您不希望在代码中将半透明设置为false,则可以在故事板中选择导航栏,并在“属性”检查器中取消选中“半透明”。

      *在旋转设备后,我打印出edgesForExtendedLayout和NavBar的translucent属性,但它们没有更改:

      class InfoViewController: UIViewController {
      
          override func viewWillTransitionToSize(size: CGSize,
              withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
          {
              super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
      
              //executes before transition
      
              coordinator.animateAlongsideTransition(//unlabeled first argument:
                  { (UIViewControllerTransitionCoordinatorContext) -> Void in
                      //executes during transition
                  },
                  completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
                      //executes after transition
      
                      print("After rotating:")
                      if self.navigationController?.navigationBar.translucent == true {
                          print("NavigationBar is translucent.")
                      }
      
                      if self.edgesForExtendedLayout == .All {
                          print("This ViewController's view will underlap a translucent NavigationBar.")
                      }
      
                  }
              )
          }
      
      --output:--
      NavigationBar is translucent.
      This ViewController's view will underlap a translucent NavigationBar.
      After rotating:
      NavigationBar is translucent.
      This ViewController's view will underlap a translucent NavigationBar.
      

      **如果NavigationBar具有背景图像,则NavigationBar的半透明属性的值将设置为true或false,具体取决于图像的alpha。请参阅UINavigationBar docs中的Translucency部分。