迅捷解决方案
此解决方案针对 Swift 中的 iOS 8 及更高版本。
我的应用的根视图控制器是一个导航控制器。最初,这个导航控制器的堆栈上有一个UIViewController,我将其称为父视图控制器。
当用户点击导航栏按钮时,父视图控制器使用包含 API 在其视图上的两个子视图控制器之间切换(在映射结果和列出的结果之间切换)。父视图控制器持有对两个子视图控制器的引用。在用户第一次点击切换按钮之前,不会创建第二个子视图控制器。第二个子视图控制器是一个表格视图控制器,并且无论其automaticallyAdjustsScrollViewInsets 属性是如何设置的,都会出现它在导航栏下方的问题。
为了解决这个问题,我在创建子表视图控制器后并在父视图控制器的 viewDidLayoutSubviews 方法中调用 adjustChild:tableView:insetTop(如下所示)。
子视图控制器的表格视图和父视图控制器的topLayoutGuide.length像这样传递给adjustChild:tableView:insetTop方法...
// called right after childViewController is created
adjustChild(childViewController.tableView, insetTop: topLayoutGuide.length)
adjustChild 方法...
private func adjustChild(tableView: UITableView, insetTop: CGFloat) {
tableView.contentInset.top = insetTop
tableView.scrollIndicatorInsets.top = insetTop
// make sure the tableview is scrolled at least as far as insetTop
if (tableView.contentOffset.y > -insetTop) {
tableView.contentOffset.y = -insetTop
}
}
语句tableView.scrollIndicatorInsets.top = insetTop 调整表格视图右侧的滚动指示器,使其在导航栏下方开始。这是微妙的,很容易被忽视,直到你意识到它。
下面是viewDidLayoutSubviews的样子……
override func viewDidLayoutSubviews() {
if let childViewController = childViewController {
adjustChild(childViewController.tableView, insetTop: topLayoutGuide.length)
}
}
请注意,上面的所有代码都出现在父视图控制器中。
我在Christopher Pickslay's answer 的帮助下解决了这个问题“iOS 7 Table view failed to autoadjust content inset”。