我最近将一些代码迁移到了新的iOS 11 beta 5 SDK .
我现在从UITableView得到一个非常令人困惑的行为 . tableview本身并不那么花哨 . 我有自定义单元格但在大多数情况下它只是为了它们的高度 .
当我用tableview推动我的视图控制器时,我得到一个额外的动画,其中单元格“向上滚动”(或者可能整个桌面框架被更改)并沿着推/弹导航动画向下移动 . 请看gif:
我在 loadView
方法中手动创建 tableview
并将自动布局约束设置为等于tableview的superview的leading,trailing,top,bottom . superview是视图控制器的根视图 .
视图控制器推送代码非常标准: self.navigationController?.pushViewController(notifVC, animated: true)
相同的代码在iOS 10上提供正常行为 .
能指点我指出错误的方向吗?
编辑:我已经制作了一个非常简单的tableview控制器,我可以在那里重现相同的行为 . 码:
class VerySimpleTableViewController : UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = String(indexPath.row)
cell.accessoryType = .disclosureIndicator
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let vc = VerySimpleTableViewController.init(style: .grouped)
self.navigationController?.pushViewController(vc, animated: true)
}
}
编辑2:我能够将问题缩小到我对UINavigationBar的定制 . 我有这样的定制:
rootNavController.navigationBar.setBackgroundImage(createFilledImage(withColor: .white, size: 1), for: .default)
其中 createFilledImage
创建具有给定大小和颜色的方形图像 .
如果我注释掉这一行,我会恢复正常行为 .
我很感激有关这件事的任何想法 .
10 回答
这是由于
UIScrollView's
(UITableView is a subclass of UIScrollview) new contentInsetAdjustmentBehavior 属性,默认情况下设置为 .automatic .您可以在任何受影响的控制器的viewDidLoad中使用以下代码段覆盖此行为:
https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior
除了maggy的答案
OBJECTIVE-C
您可以使用NSProxy在整个应用程序中立即编辑此行为,例如didFinishLaunchingWithOptions:
这似乎更像是一个错误,而不是预期的行为 . 当导航栏不是半透明或设置背景图像时会发生这种情况 .
如果您只是将contentInsetAdjustmentBehavior设置为.never,则不会在iPhone X上正确设置内容插入内容,例如内容将进入滚动条下方的底部区域 .
有两件事要做:
1.阻止scrollView在推/弹上动画
2.保留.automatic行为,因为iPhone X需要它 . 在肖像中,内容将低于底部滚动条 .
XIB中的 New simple solution: :只需在主视图顶部添加新的UIView,顶部,前导和尾随superview,高度设置为0.您不必将其连接到其他子视图或任何其他内容 .
Old solution:
注意:如果您在横向模式下使用UIScrollView,它仍然没有正确设置水平插入(另一个错误?),因此您必须将滚动视图的前导/尾随固定到IB中的safeAreaInsets .
注2:下面的解决方案还有一个问题,即如果tableView滚动到底部,并且你按下控制器并弹回,它将不再在底部 .
以下是我设法解决此问题的方法 while still allowing iOS 11 to set insets automatically . 我正在使用
UITableViewController
.在故事板(或programmatically)的视图控制器中选择"Extend edges under top bars"和"Extend edges under opaque bars" . 安全区域插入将阻止您的视图进入顶部栏 .
检查故事板中表格视图上的"Insets to Safe Area"按钮 . (或
tableView.insetsContentViewsToSafeArea = true
) - 这可能没有必要,但这就是我所做的 .将内容插入调整行为设置为"Scrollable Axes"(或
tableView.contentInsetAdjustmentBehavior = .scrollableAxes
) -.always
也可能有效,但我没有测试 .如果其他所有方法都失败了,还有另外一件事
覆盖
viewSafeAreaInsetsDidChange
UIViewController
方法以获取表视图以强制将滚动视图插入设置为安全区域insets . 这与Maggy的答案中的'Never'设置一起使用 .注意:
self.tableView
和self.view
应与UITableViewController
相同我可以重现iOS 11.1的错误,但似乎自iOS 11.2以来该错误已得到修复 . 见http://openradar.appspot.com/34465226
请确保以上代码,添加如下附加代码 . 它解决了这个问题
如果你使用标签栏,集合视图的底部内容插入将为零 . 为此,请将以下代码放在viewDidAppear中:
在我的情况下,这工作(把它放在viewDidLoad中):
删除此代码工作对我来说