UITableView 部分索引在 iOS 7 中定位错误的单元格,顶行隐藏在导航栏下

Posted

技术标签:

【中文标题】UITableView 部分索引在 iOS 7 中定位错误的单元格,顶行隐藏在导航栏下【英文标题】:UITableView section index targets wrong cell in iOS 7, top row hides under navigation bar 【发布时间】:2013-11-20 20:06:51 【问题描述】:

我有一个带有 UITableView 的应用程序,它通过 NSFetchedResultsController 提供数据。表格视图按字母顺序排序并按首字母划分为多个部分。

在我的手机升级到 ios 7 时,我注意到部分索引标题无法正常工作:

行动: 点击部分索引标题“M”以滚动列表到以字母 M 开头的项目。

预期结果: 表格视图滚动到 M 节中的第一项,节标题保持可见。

实际结果: 表格视图滚动到 M 部分中的 second 项,部分标题不可见。第一项存在,但就在可见框的上方。

在 iOS 6 上,一切正常。

附带说明,顶行上方和底行下方的橡皮筋效果也有一个奇怪的行为,通过“拉伸”橡皮筋,我可以看到第一行,但只要我松开它,第一行再次滚动到屏幕外。底行也是如此。

更新

这很可能是由于从 Xcode 4.6 自动布局迁移到 Xcode 5 自动布局引起的,我听说这不兼容。也许一些约束变坏了?我还在努力寻找它的原因。

Interface Builder 中的场景由一个 UIView 组成,该 UIView 包含两个子视图——两个 UITableView 相互重叠。通过导航栏顶部的 UISegmentedControl 切换两个可见视图中的哪一个。底部有一个标签栏。

我已经在 IB 中手动布置了界面,因此它们都是全屏的,这是单独完成的,即没有约束指定相同的宽度/高度等。我使用的约束没有;自动布局建议的约束;而且我还尝试按照@duci9y 的建议在两个表格视图上制作 contentInsets。

按照@Popara 的建议,导航栏设置为不透明。

结束说明

如果我能理解如何将表格视图设置为全屏,除了缩小以确保它们不会在导航栏和标签栏下方重叠。

【问题讨论】:

检查表格视图的“内容插入”。他们是不是搞砸了?有负值吗? 不,没有对 contentInsets 做任何事情,但是您将我引向了 Autolayout 的方向,这似乎比我的子类化要好得多。 如何设置表格视图的框架和约束?您应用了哪些限制条件? 我已经用有关如何设置框架(手动在 IB 中)以及我尝试过哪些限制的信息更新了问题。 此***.com/questions/20345000/…> 可能对您有所帮助。请参阅问题和接受的答案。 【参考方案1】:

对我来说,这听起来不像是自动布局问题。在包含表格视图的视图控制器中,在viewDidLoad 中运行self.automaticallyAdjustsScrollViewInsets = YES;

表格视图控制器是否被推送到导航控制器上?那么这应该就是你需要做的所有事情了。

如果没有,您需要阅读属性edgesForExtendedLayouttopLayoutGuide。如果您的视图控制器包含自己的导航栏,则需要覆盖后者。

topLayoutGuide 告诉您的视图控制器任何滚动视图应该有多少顶部内容插入(这适用于表格视图,因为它们继承自滚动视图)。由于在 iOS7 上,您的表格视图位于导航栏的后面(因为它是半透明的),所以它的顶部布局指南必须设置在导航栏的正下方。

如果你的view层级比较复杂(table view不是view controller view的直接子view),那么你可以手动设置content inset:

tableView.contentInset = UIEdgeInsetsMake(CGRectGetMaxY(navigationBar.frame), 0, 0, 0);

【讨论】:

这并没有完全解决问题(我无法让顶部插图恰好对齐——它偏离了状态栏的高度),但对我来说是最有帮助的最远距离。 是的,使用 topLayoutGuide 时会考虑状态栏,但是当您手动执行此操作时,您可以这样做:CGRectGetMaxY(navigationBar.frame)【参考方案2】:

在 iOS 7 中将您的 tableview 框架 delta y 设置为 20

试试这个。

【讨论】:

【参考方案3】:

在ios7 y轴从顶部开始可能是导航栏是否存在 如果您希望 y 轴从导航栏下方开始(导航栏后的 y-axis==0 ) 您必须在 -viwDidLoad 方法中进行一些编码,例如:-

- (void)viewDidLoad

    [super viewDidLoad];
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;
    //here your initilization for table and others starts

【讨论】:

【参考方案4】:

iOS 6 和 iOS 7 的主要 UI 区别在于 iOS 7 中的 viewcontroller 中包含状态栏。这意味着您的 view controller 比 iOS6 大 20 px。你必须调整你的项目。首先根据 iOS 6 设计你的项目,这是更好的方法,你必须有很多实践,现在将每个项目的 Δy 设置为 20。

或者根据 iOS 7 设计你的项目并将 Δy 设置为 -20

有关详细信息,请参阅此Post。

【讨论】:

【参考方案5】:

是的,这是 AutoLayout 过渡问题。

似乎表格视图边界的定位不正确。

在iOS7中ViewControllers位于导航栏下方,即共享相同的起始视点(0,0),所以第一个单元格被导航栏+节标题覆盖。

更可取的路径是设置您的导航栏不是半透明的(可能通过外观代理)。 另一种选择是在 loadView 或 viewDidLoad 中以某种方式抵消导航栏高度增量的表格视图。

祝你好运。

【讨论】:

【参考方案6】:

假设您的表格视图位于导航控制器/标签栏控制器层次结构中的控制器中:

self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);

【讨论】:

以上是关于UITableView 部分索引在 iOS 7 中定位错误的单元格,顶行隐藏在导航栏下的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 7 上压缩的 UITableView sectionIndexTitles

如何判断何时点击了 UITableView 部分索引字母?

IOS 7:从分组样式 UITableView 的一部分中删除边框

UITableView 类似 Contacts ios 7 中的社交部分

在 iOS 的 UITableView 中滚动时索引错误

iOS - TableView - 在点击按钮上获取标题部分的索引