我最近将一些代码迁移到了新的iOS 11 beta 5 SDK。
我现在从UITableView获得了一个非常令人困惑的行为。 tableview本身并不那么花哨。我有自定义单元格,但大多数情况下它只是为了它们的高度。
当我用tableview推动我的视图控制器时,我得到一个额外的动画,其中单元格"向上滚动" (或者可能整个tableview框架已更改)并沿着推/弹导航动画向下。请参阅gif:
我在tableview
方法中手动创建loadView
,并将自动布局约束设置为等于tableview的超级视图的前导,尾随,顶部和底部。 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
创建具有给定大小和颜色的方形图像。
如果我注释掉这一行,我会恢复正常行为。
我很感激对此事的任何想法。
答案 0 :(得分:143)
这是由于 flag group url
0 0 a abc
1 0 a de
2 1 a fghi
3 1 b jkl
4 0 b m
(UITableView是UIScrollview的子类)新 UIScrollView's
属性,设置为 { {1}} 默认情况下。
您可以在任何受影响的控制器的viewDidLoad中使用以下代码段覆盖此行为:
contentInsetAdjustmentBehavior
https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior
答案 1 :(得分:21)
除了maggy的回答
<强>目的-C 强>
if (@available(iOS 11.0, *)) {
scrollViewForView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
此问题是由iOS 11中
safeAreaInsets
的错误引起的 导航期间视图控制器的视图设置不正确 转换,应在iOS 11.2中修复。设置contentInsetAdjustmentBehavior
到.never
不是一个很好的解决方法 因为它可能会产生其他不良副作用。如果你这样做 使用变通方法,你应该确保删除iOS版本&gt; = 11.2- 由smileyborg(Apple的软件工程师)提及
答案 2 :(得分:7)
您可以在整个应用程序中使用NSProxy编辑此行为,例如didFinishLaunchingWithOptions:
if (@available(iOS 11.0, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
答案 3 :(得分:4)
以下是我如何设法修复此问题同时仍允许iOS 11自动设置插入。我正在使用UITableViewController
。
tableView.insetsContentViewsToSafeArea = true
) - 这可能没有必要,但这就是我所做的。tableView.contentInsetAdjustmentBehavior = .scrollableAxes
) - .always
也可能有用,但我没有测试。如果其他所有方法都失败,还可以尝试另外一件事:
覆盖viewSafeAreaInsetsDidChange
UIViewController
方法以获取表视图以强制将滚动视图插入设置为安全区域insets。这与“永远不会”相关联。设置Maggy的答案。
- (void)viewSafeAreaInsetsDidChange {
[super viewSafeAreaInsetsDidChange];
self.tableView.contentInset = self.view.safeAreaInsets;
}
注意:self.tableView
和self.view
应与UITableViewController
答案 4 :(得分:3)
这似乎更像是一个错误,而不是预期的行为。当导航栏不是半透明或设置背景图像时会发生这种情况。
如果您只是将contentInsetAdjustmentBehavior设置为.never,则在iPhone X上无法正确设置内容插入内容,例如内容将进入滚动条下方的底部区域。
有必要做两件事:
1.阻止scrollView在推/弹簧上动画
2.保留.automatic行为,因为iPhone X需要它。在纵向中,内容将低于底部滚动条。
XIB中的新简单解决方案:只需在主视图顶部添加新的UIView,顶部,前导和尾部到superview,高度设置为0.您不必连接它到其他子视图或任何东西。
旧解决方案:
注意:如果你在横向模式下使用UIScrollView,它仍然没有正确设置水平插入(另一个错误?),所以你必须将scrollView的前导/尾随引脚到IB中的safeAreaInsets。
注意2:下面的解决方案还有一个问题,即如果tableView滚动到底部,并且你按下控制器并弹回,它将不再位于底部。
override func viewDidLoad()
{
super.viewDidLoad()
// This parts gets rid of animation when pushing
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .never
}
}
override func viewDidDisappear(_ animated: Bool)
{
super.viewDidDisappear(animated)
// This parts gets rid of animation when popping
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .never
}
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
// This parts sets correct behaviour(insets are correct on iPhone X)
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .automatic
}
}
答案 5 :(得分:2)
请确保以上代码,添加其他代码,如下所示。它解决了这个问题
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // print(thisUISBTV.adjustedContentInset)
}
答案 6 :(得分:2)
此外,如果使用标签栏,则集合视图的底部内容插入将为零。为此,请将以下代码放在viewDidAppear:
中if #available(iOS 11, *) {
tableView.contentInset = self.collectionView.safeAreaInsets
}
答案 7 :(得分:2)
我可以重现iOS 11.1的错误,但似乎自iOS 11.2以来该错误已得到修复。 见http://openradar.appspot.com/34465226
答案 8 :(得分:1)
在我的情况下,这工作(把它放在viewDidLoad中):
self.navigationController.navigationBar.translucent = YES;
答案 9 :(得分:0)
为我删除此代码工作
self.edgesForExtendedLayout = UIRectEdgeNone
答案 10 :(得分:0)
删除collectionView
或tableView
顶部的多余空间
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
//tableView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
代码collectionView
或tableView
上方位于导航栏下方。
下面的代码阻止集合视图进入导航
self.edgesForExtendedLayout = UIRectEdge.bottom
但是我喜欢为 UICollectionView
使用以下逻辑和代码边缘插入值应用于矩形以缩小或扩展 该矩形代表的区域。通常,使用边缘插图 在视图布局期间修改视图的框架。正值导致 要插入(或缩小)指定数量的帧。负 值导致框架以指定的位置开始(或扩展) 数量。
collectionView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
//tableView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
UICollectionView
的最佳方法func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
}
答案 11 :(得分:0)
if #available(iOS 11, *) {
self.edgesForExtendedLayout = UIRectEdge.bottom
}
我正在将UISearchController与具有表视图的自定义resultsControllers一起使用。将新控制器推入结果控制器会导致表格视图进入搜索状态。
上面列出的代码完全解决了问题