从 iOS7 开始,我的 UITableView
顶部有额外的空间,其样式为 UITableViewStyleGrouped
。
这是一个例子:
https://i.stack.imgur.com/yNYTL.png
tableview 从第一个箭头开始,有 35 个像素的无法解释的填充,然后绿色标题是 viewForHeaderInSection
返回的 UIView
(其中部分为 0)。
谁能解释这个 35 像素的数量来自哪里以及如何在不切换到 UITableViewStylePlain
的情况下摆脱它?
更新(答案):
在 iOS 11 及更高版本中:
tableView.contentInsetAdjustmentBehavior = .never
UITableView
不喜欢被分配高度为 0.0 的标题。查看 stackoverflow.com/a/31223403/1394534 了解更多详情。
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, CGFLOAT_MIN)];
注意:如果您在矩形的高度中使用 0.0f
,它只会被忽略。所以我们尽可能使用最接近零的 CGFloat (至少这对我来说“有效”......只是不是理想的解决方案)。
我得到了以下帮助:
YouStoryboard.storyboard > YouViewController > Attributes inspector > Uncheck - 调整滚动视图插图。
https://i.stack.imgur.com/CUVgX.png
我又玩了一会儿,似乎这是设置 tableView 的 tableHeaderView = nil
的副作用。
因为我的 tableView 有一个动态显示的 tableHeaderView
,所以当我需要隐藏 tableHeaderView
,而不是执行 self.tableView.tableHeaderView = nil;
时,我会这样做:
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];
我更喜欢这个解决方案而不是设置一个有点随意的 contentInset.top
,因为我也动态使用 contentInset.top
。每次重新计算 contentInset.top
时都必须记住删除额外的 35px 是很乏味的。
Debug > Color Misaligned Images
以亲自查看。)您不想这样做。
UITableViewHeaderFooterView
而不是 UIView。 CGFLOAT_MIN
的工作原理与 0.01f
相同,但理论上更好。
尝试更改 UITableView
从 UIScrollView
继承的 contentInset
属性。
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
这是一种解决方法,但它有效
contentTableView.contentInset = UIEdgeInsetsMake(-20, 0, -20, 0);
最适合我,因为顶部和底部有 20 个额外像素。
对于 IOS 7,如果您在视图控制器中分配表视图,您可以查看
self.edgesForExtendedLayout = UIRectEdgeNone;
你的问题似乎和我的相似
更新:
iOS 9.x 中的 Swift:
self.edgesForExtendedLayout = UIRectEdge.None
斯威夫特 3:
self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)
UITableView
上工作。问题源于我的 UITableView
位于 UINavigationController
内的 UIViewController
上,这导致表格内容下降 44 点,因此初始内容不在 navBar
后面。不过,我的布局不需要这样做,所以它只是引起了问题。最终,我将代码更改为 automaticallyAdjustsScrollViewInsets
,它也可以正常工作。
edgesForExtendedLayout = []
self.automaticallyAdjustsScrollViewInsets = NO;
试试看,你可以应对的!
uncheck Adjust scroll view insets
好。因为有时我们不使用故事板来构建我们的 UI。
self.tableView.contentInsetAdjustmentBehavior = .never
您可以检测您的应用程序是否运行 iOS7 或更高版本,并在您的表视图委托中添加这两个方法(通常在您的 UIViewController 代码中)
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return CGFLOAT_MIN;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return CGFLOAT_MIN;
}
这可能不是一个优雅的解决方案,但对我有用
斯威夫特版本:
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return section == 0 ? 14 : 24 }
我找到了原始错误的原因并创建了一个示例项目来展示它。我相信有一个iOS7错误。
从 iOS7 开始,如果你创建了一个带有 Grouped 样式的 UITableView,但在第一个布局上没有设置委托,那么你设置了一个委托并调用 reloadData,顶部将有一个 35px 的空间永远不会消失。
请参阅我制作的展示错误的项目:https://github.com/esilverberg/TableViewDelayedDelegateBug
如果第 24 行处于活动状态,
[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];
顶部会有一个额外的 35 px 空间。如果第 27 行处于活动状态并且第 24 行被注释掉,
self.tableView.delegate = self;
顶部没有空间。就像 tableView 在某处缓存结果并且在设置委托并调用 reloadData 后不重绘自身。
tableView:heightForHeaderInSection:
和 tableView:heightForFooterInSection:
返回 0 你也会遇到这个问题。实现上面的协议方法并返回 0.01f 为我修复了它。
取消选中“调整滚动视图插图”
https://i.stack.imgur.com/keeaD.png
另一个快速评论...即使在 XCode 6.1 中,也存在一个错误,即在 UIScrollViews
、UITextViews
和 UITableViews
的顶部出现垂直空格。
https://i.stack.imgur.com/2JLvN.png
有时,解决此问题的唯一方法是进入情节提要并拖动问题控件,使其不再是页面上的第一个子视图。
https://i.stack.imgur.com/qNA76.png
(感谢 Oded 为我指明了这个方向……我发布此评论,只是为了添加一些屏幕截图,以展示症状并进行修复。)
iOS 15 的解决方案:
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
在整个项目中修复:
if #available(iOS 15.0, *) {
UITableView.appearance().sectionHeaderTopPadding = 0
}
更多详情:Extra padding above table view headers in iOS 15
注意:这个 only applies 到 UITableView.Style.plain
。
在使用分组的 TableView 时使用它来避免 viewWillAppear 中的边框切割
self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0);
根据 Apple 的 transition guide for iOS7,滚动视图的内容插入会自动调整。 automaticallyAdjustsScrollViewInsets 的默认值设置为 YES。
具有 UITableView 的 UIViewController 应将此属性设置为 NO。
self.automaticallyAdjustsScrollViewInsets = NO;
这会成功的。
编辑1:
另外,可以尝试 -
self.navigationController.navigationBar.translucent = YES;
这也删除了顶部的额外填充。
上面很多以前的答案都太老套了。如果 Apple 决定修复这种意外行为,它们将在未来的任何时候中断。
问题的根源:
UITableView 不喜欢有高度为 0.0 的标题。如果你想要做的是有一个高度为 0 的标题,你可以跳转到解决方案。即使稍后您为标题分配了非 0.0 的高度,UITableView 也不喜欢最初分配高度为 0.0 的标题。
解决方案:
然后,最简单可靠的解决方法是确保将标题高度分配给表格视图时不为 0。
像这样的东西会起作用:
// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, CGFLOAT_MIN)];
self.tableView.tableHeaderView = tableViewHeaderView;
这样的事情会在某些时候导致问题(通常是在滚动之后):
// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
self.tableView.tableHeaderView = tableViewHeaderView;
tableView.tableHeaderView
实际上是行内容上方的辅助视图。在你的答案出来之前,我一直对部分标题感到困惑。
CGFLOAT_MIN
已替换为 CGFloat.leastNormalMagnitude
故事板:
只需在 View Controller 的选项中取消选中:Adjust Scroll View Insets
https://i.stack.imgur.com/J4C7u.png
代码:
self.automaticallyAdjustsScrollViewInsets = false
这是使用 Swift 3 的 iOS 10 的解决方案:
您可以通过实施 UITableViewDelegate
中的以下方法来消除顶部和底部填充。
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return CGFloat.leastNormalMagnitude
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
{
return CGFloat.leastNormalMagnitude
}
这段代码对我有用,对我来说最好的答案是用 objective-C
写的,所以我把它转换成 Swift。
对于 Swift 4.0+
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: .leastNonzeroMagnitude))
只需将其写入 viewDidLoad()
,它就会像魅力一样工作。
对于 iOS 15+,以上一个不起作用,所以使用这个:-
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
对于 iOS 15+,如果您想为整个项目应用更改,请使用以下命令:-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 15.0, *) {
UITableView.appearance().sectionHeaderTopPadding = 0.0
}
}
所以我在这里尝试了每一种方法,但这次都没有帮助。我的案例是 iOS 9 上的分组表视图。我真的不知道为什么以及如何发现这个,但对我来说,将 tableViewHeader
设置为具有至少 0.01
高度的 UIView
是可行的。 CGRectZero
没有帮助,没有任何帮助:
tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01))
只需将以下内容添加到 VC 中的 viewDidLoad 中:
self.automaticallyAdjustsScrollViewInsets = NO;
就我而言,这对我有帮助。我也支持ios6。
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = NO;
self.automaticallyAdjustsScrollViewInsets = NO;
}
这就是如何通过 Storyboard 在 iOS 11 和 Xcode 9.1 中轻松修复它:
选择表视图 > 大小检查器 > 内容插入:从不
automaticallyAdjustsScrollViewInsets
斯威夫特:iOS 我在滚动视图上有表格视图..当我在同一屏幕上单击“返回”时。滚动视图在顶部占用更多空间..为了解决这个问题,我使用了:
self.automaticallyAdjustsScrollViewInsets = false
一个布尔值,指示视图控制器是否应自动调整其滚动视图插图。默认值为 true,它允许视图控制器调整其滚动视图插入以响应状态栏、导航栏和工具栏或选项卡栏所占用的屏幕区域。如果您想自己管理滚动视图插入调整,请设置为 false,例如当视图层次结构中有多个滚动视图时。
感谢@Aurelien Porte 的回答。这是我的解决方案
此问题的原因:-
UITableView 不喜欢有高度为 0.0 的标题。如果你想要做的是有一个高度为 0 的标题,你可以跳转到解决方案。即使稍后您为标题分配了非 0.0 的高度,UITableView 也不喜欢最初分配高度为 0.0 的标题。
在 ViewDidLoad 中:-
self.edgesForExtendedLayout = UIRectEdge.None
self.automaticallyAdjustsScrollViewInsets = false
不需要这样的东西:-
self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)
在 heightForHeaderInSection
委托中:-
if section == 0
{
return 1
}
else
{
return 40; // your other headers height value
}
在 viewForHeaderInSection
委托中:-
if section == 0
{
// Note CGFloat.min for swift
// For Objective-c CGFLOAT_MIN
let headerView = UIView.init(frame: CGRectMake(0.0, 0.0, self.myShaadiTableview.bounds.size.width, CGFloat.min))
return headerView
}
else
{
// Construct your other headers here
}
具体来说,要从顶部删除 tableviewHeader 空间,我进行了以下更改:
YouStoryboard.storyboard > YouViewController > Select TableView > Size inspector > Content insets - 设置为从不。
https://i.stack.imgur.com/j9n14.png
我假设这只是新 UITableViewStyleGrouped
样式的一部分。它在所有分组表视图中,似乎没有任何直接的方法来控制该空间。
如果该空间由 UIView
表示,则可以搜索 UITableView
的所有 subviews
以找到该特定视图并直接对其进行编辑。但是,也有可能该空间只是标题和单元格开始之前的硬编码偏移量,并且没有任何方法可以编辑它。
搜索所有子视图(我会在表格没有单元格时运行此代码,以便更容易阅读输出):
- (void)listSubviewsOfView:(UIView *)view {
// Get the subviews of the view
NSArray *subviews = [view subviews];
// Return if there are no subviews
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
NSLog(@"%@", subview);
// List the subviews of subview
[self listSubviewsOfView:subview];
}
}
UITableViewCellScrollView
)教会了我们一件事,那就是让内置类的视图层次结构保持不变。
po [((UIApplication *)UIApplication.sharedApplication).keyWindow recursiveDescription]
,您会看到表格标题、第一节标题或第一个单元格(取决于您使用的内容)自然会留下 35 像素的边框......嘘。
我的答案将是更一般的答案,但也可以应用于此。
如果(ViewController 的)根视图或根视图的第一个子视图(子视图)是 UIScrollView(或 UIScrollView 本身)的子类,并且如果
self.navigationController.navigationBar.translucent = YES;
框架会自动设置预先计算好的 contentInset。
为避免这种情况,您可以这样做
self.automaticallyAdjustsScrollViewInsets = NO;
但就我而言,我无法做到这一点,因为我正在实现具有 UIView 组件的 SDK,该组件可供其他开发人员使用。该 UIView 组件包含 UIWebView (将 UIScrollView 作为第一个子视图)。如果该组件被添加为 UIViewController 视图层次结构中的第一个子组件,系统将应用自动插入。
我已经通过在添加 UIWebView 之前添加带有框架 (0,0,0,0) 的虚拟视图来解决此问题。
在这种情况下,系统没有找到 UIScrollView 的子类作为第一个子视图并且没有应用插图
self.automaticallyAdjustsScrollViewInsets = false
唯一对我有用的是:
迅速:
tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0
目标-C:
self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 0;
此外,我还有第一部分的额外空间。那是因为我错误地使用了 tableHeaderView
属性。通过添加以下内容也修复了该问题:
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0.01))
Swift 4 代码:对于没有节标题的表格视图,您可以添加以下代码:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
你会得到标题间距为0。
如果您想要特定高度的标题,请传递该值:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return header_height
}
以及来自 viewForHeaderinSection 委托的视图。
2019年回答:
你只要这样做
tableView.contentInsetAdjustmentBehavior = .never
奇异微妙的gotchya ->
这些天,Tableviews 有一个非常奇怪的行为:
在带有缺口(XR 等)的设备上,它不会告诉您添加更多插图,但前提是表格从屏幕的物理顶部开始。如果你不是从屏幕顶部开始,它不会那样做,但是这两种情况都是 >> 不相关 << 到 safeAreaInsets ......这很令人困惑
所有这些都是完全没有记录的......你可以浪费几个小时来弄清楚这一点。
如果您确实需要从屏幕/表格顶部实际开始测量,
实际上只是去:
tableView.contentInsetAdjustmentBehavior = .never
一个很好的例子显然是当您在表格顶部添加某种横幅或类似的东西时,这在当今很常见,您只需将表格的顶部插图设置为您的横幅/等在运行时变为的任何高度。
为此,您必须使用
tableView.contentInsetAdjustmentBehavior = .never
称呼 :/
奖金gotchya
不要忘记,这些天几乎总是在动态加载一些信息(用户图片、描述等),因此在信息到达之前,您无法将这些值设置为最终需要的值。另一个问题。 :/
所以你会有这样的代码:
func setTableOffsetOnceFlagAreaSizeIsKnown() {
tableView.contentInset.top = yourSpecialFlagViewUpTop.bounds.height
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setTableOffsetOnceFlagAreaSizeIsKnown()
}
我有与 arielyz 相同的修复方法。一旦我将 UITableView 移动为不是父视图的第一个子视图,它就消失了。我的空间是 20 像素,而不是 35。
我无法在纵向 xib 中重新创建它,只能在横向 xib 中重新创建它。如果我可以在一个简单的演示应用程序中重现它,我稍后会提交一个雷达错误。
我认为制作 UIEdgeInsets -35 0 0 0 很乏味。就我而言,我实现了 tableView: heightForHeaderInSection: 方法,它有可能返回 0。
当我将 0 更改为 0.1f 时,问题就消失了。
collectionview
时不起作用。 (当 tableview 在collectionviewcell
内时)