为什么嵌入 UINavigationController 的 UIVewController 的第一个子视图的位置会发生变化?

Why does the first subview's position of a UIVewController embedded in a UINavigationController get altered?

当说 ViewController 嵌入 UINavigationController 时,我注意到 UITablesViewsViewController 中有一些奇怪的行为。以下是一个简单原型的代码,用于选择不同的 UITableViews 在场景中显示,不包括 TableView 的方法并选择要显示的视图。

class ChooseTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

  var tableViewA: UITableView = UITableView()
  var tableViewB: UITableView = UITableView()

  var colors: [String] = ["red", "blue", "green"]
  var shapes: [String] = ["triangle", "circle", "square"]

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    tableViewA.frame       = CGRectMake(0, 50, 320, 200)
    tableViewA.delegate    = self
    tableViewA.dataSource  = self
    tableViewA.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cellTableViewA")

    tableViewB.frame       = CGRectMake(0, 50, 320, 200)
    tableViewB.delegate    = self
    tableViewB.dataSource  = self
    tableViewB.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cellTableViewB")

    self.view.addSubview(tableViewB)
    self.view.addSubview(tableViewA)
    tableViewB.hidden = true

    let segmentSelectorLabels = ["one", "two"]
    let segmentSelector = UISegmentedControl(items: segmentSelectorLabels)
    segmentSelector.frame = CGRectMake(self.view.frame.width/2 - 50, self.view.frame.height - 100, 100, 40)
    self.view.addSubview(segmentSelector)
    segmentSelector.selectedSegmentIndex = 0
    segmentSelector.addTarget(self, action: "chooseTable:", forControlEvents: .ValueChanged)
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

...
}

这是 ChooseTableViewController 未嵌入 UINavigationController 和嵌入

时的结果

Simulators results

在另一个项目中,只需添加

即可修复该行为
let emptyView:UIView = UIView()

self.view.addSubiew(emptyView)

其中 emptyView 是第一个添加的子视图。这是将 UITableViews 放置在适当位置的老套解决方案。对此行为的任何见解表示赞赏。

将 table 视图的帧原点 y 位置设置为 0。在故事板中找到此视图控制器的 "Extended Edges" 设置并关闭 "Under Top Bars"。

取消选中属性检查器中 viewcontroller 的 "Adjust Scroll View Insets" 或在代码中执行:

self.automaticallyAdjustsScrollViewInsets = NO; (Obj-C) self.automaticallyAdjustsScrollViewInsets = false (Swift)

更多解释:

如果此 属性 设置为 YES / true viewcontroller - 顾名思义 - 自动调整其 first 滚动视图的插图查看层次结构。如果您的 scrollview / tableview / textview / webview 占据了整个屏幕并且其中的一部分通常被状态栏/导航栏/标签栏或工具栏隐藏,这将很有帮助。然后这些插图使您的内容出现在顶部栏下方/底部栏上方。这虽然只发生在滚动视图/ ... 是视图层次结构中的 TOP MOST 子视图(= 索引 0 处的子视图)时。为了让事情更清楚,我上传了四个例子:

  1. 属性 设置为 YES / true 和视图层次结构中的两个文本视图(在索引 0 和 1):如您所见,仅为 [=37= 设置了插图]first 滚动视图

  2. 属性 设置为 NO / false 和视图层次结构中的两个文本视图(索引 0 和 1):如您所见,根本没有设置任何插图

  3. 属性 设置为 YES / true,一个按钮(索引 0 处的子视图)和两个文本视图(索引 1 和 2):如您所见,根本没有设置任何插图尽管 属性 是 YES / true。那是因为没有滚动视图是视图层次结构中的 TOP MOST 子视图。

  4. 属性 设置为 YES / true 索引 0 处的视图层次结构中的 textview 占据了整个屏幕:如您所见,尽管 textview 占据了整个屏幕(开始在 0,0) 文本没有被 status- / navigationbar 隐藏,因为 viewcontroller 自动调整了文本视图(滚动视图)的插入。

我希望我能帮助使事情更清楚一些。 :)