为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

时间:2022-09-07 08:17:51

Starting in iOS7, there is additional space at the top of my UITableView's which have a style UITableViewStyleGrouped.

从iOS7开始,在我的UITableView顶部还有一个额外的空间,它有一个uitableviewstylegroups。

Here is an example:

这是一个例子:

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

The tableview starts at the first arrow, there is 35 pixels of unexplained padding, then the green header is a UIView returned by viewForHeaderInSection (where the section is 0).

tableview从第一个箭头开始,有35个像素的无法解释的填充,然后绿色的标题是viewForHeaderInSection(在该部分为0)返回的UIView。

Can anyone explain where this 35 pixel amount is coming from and how I can get rid of it without switching to UITableViewStylePlain?

有人能解释一下这35个像素的来源吗?我怎么能在不切换到UITableViewStylePlain的情况下去掉它呢?

50 个解决方案

#1


834  

I was helped by the following:

我得到以下帮助:

YouStoryboard.storyboard > YouViewController > Attributes inspector > Uncheck - Adjust scroll view insets.

YouStoryboard。故事板> YouViewController >属性检查器>取消检查-调整滚动视图内嵌。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

#2


276  

I played around with it a bit more and it seems like this is a side-effect of setting the tableView's tableHeaderView = nil.

我在这里多做了一点,看起来这是设置tableView的tableHeaderView = nil的副作用。

Because my tableView has a dynamically appearing tableHeaderView, when I need to hide the tableHeaderView, instead of doing self.tableView.tableHeaderView = nil;, I do:

因为我的tableView有一个动态显示的tableHeaderView,当我需要隐藏tableHeaderView时,而不是做self。tableView。表头视图= nil;

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];

I like this solution better than setting a somewhat arbitrary contentInset.top because I use the contentInset.top dynamically as well. Having to remember to remove an extra 35px whenever I recalculate contentInset.top is tedious.

我更喜欢这个解决方案,而不是设置一个有点随意的contentInset。top因为我使用了contentInset。高级动态。每当我重新计算contentInset时,必须记住删除一个额外的35px。是乏味的。

#3


168  

For IOS 7 if you are allocing a tableview in a view controller you may look into

对于ios7,如果你在视图控制器中分配一个tableview,你可以查看

self.edgesForExtendedLayout = UIRectEdgeNone;

your problem seemed similar to mine

你的问题和我的相似。

Update:

更新:

Swift in iOS 9.x:

斯威夫特在iOS 9. x:

self.edgesForExtendedLayout = UIRectEdge.None

Swift 3 :

斯威夫特3:

self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)

#4


147  

Try changing the contentInset property that UITableView inherits from UIScrollView.

尝试修改UITableView从UIScrollView继承的contentInset属性。

self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);

It's a workaround, but it works

这是一个变通方案,但它确实有效

#5


125  

self.automaticallyAdjustsScrollViewInsets = NO;

try, you can deal with it!

试试看,你能应付的!

#6


59  

You could detect if your app is running iOS7 or greater and add this two methods in your table view delegate (usually in your UIViewController code)

你可以检测你的应用是否在运行iOS7或更多并在你的表视图委托中添加这两个方法(通常在你的UIViewController代码中)

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

This maybe is not an elegant solution but works for me

这可能不是一个优雅的解决方案,但对我来说是可行的

#7


48  

I have found the cause of my original bug and created a sample project showcasing it. I believe there is an iOS7 bug.

我找到了原始bug的原因,并创建了一个示例项目来展示它。我相信是iOS7有问题。

As of iOS7, if you create a UITableView with the Grouped style, but do not have a delegate set on first layout, then you set a delegate and call reloadData, there will be a 35px space at the top that will never go away.

在iOS7中,如果您使用分组样式创建一个UITableView,但是没有在第一个布局上设置一个委托,那么您就设置一个委托并调用reloadData,在顶部将有一个35px的空间永远不会消失。

See this project I made showcasing the bug: https://github.com/esilverberg/TableViewDelayedDelegateBug

请看我制作的这个项目,它展示了这个bug: https://github.com/esilverberg/TableViewDelayedDelegateBug

Specifically this file: https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

特别是这个文件:https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

If line 24 is active,

如果第24行是活动的,

[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];

there will be an extra 35 px space at the top. If line 27 is active and 24 is commented out,

顶部将有一个额外的35像素空间。如果第27行是活动的,第24行被注释掉,

self.tableView.delegate = self;

no space at the top. It's like the tableView is caching a result somewhere and not redrawing itself after the delegate is set and reloadData is called.

顶部没有空间。就像tableView会缓存一个结果,而不会在设置委托并调用reloadData之后重新绘制自己。

#8


45  

Uncheck "Adjust Scroll View insets"

取消“调整滚动视图嵌套”

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

#9


44  

Another quick comment... even in XCode 6.1, there is a bug with vertical spaces appearing at the top of UIScrollViews, UITextViews and UITableViews.

另一个快速评论……即使在XCode 6.1中,在UIScrollViews、UITextViews和UITableViews的顶部也出现了垂直空格的bug。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

Sometimes, the only way to fix this issue is to go into the Storyboard and drag the problem control so it's no longer the first subview on the page.

有时,解决这个问题的唯一方法是进入故事板并拖动问题控件,这样它就不再是页面上的第一个子视图。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

(My thanks to Oded for pointing me in this direction... I'm posting this comment, just to add a few screenshots, to demonstrate the symptoms and fix.)

(感谢Oded指正我的方向……)我发布这条评论,只是为了添加一些截图,以展示症状和修复。

#10


37  

According to this transition guide for iOS7 by Apple, the scroll view’s content insets is automatically adjusted. The default value of automaticallyAdjustsScrollViewInsets is set to YES.

根据苹果iOS7的转换指南,滚动视图的内容会自动调整。automaticallycontrollsscrollviewinsets的默认值设置为YES。

The UIViewController which has the UITableView should set this property to NO.

拥有UITableView的UIViewController应该将这个属性设置为NO。

self.automaticallyAdjustsScrollViewInsets = NO;

This will do the trick.

这样就可以了。

EDIT 1:

编辑1:

Also, one could try -

还有,我们可以试试-

self.navigationController.navigationBar.translucent = YES;

This also removes the extra padding on the top.

这也消除了顶部的额外填充。

#11


35  

While using grouped TableView use this to avoid border cutting in viewWillAppear

使用分组的TableView时,可以使用它来避免viewWillAppear中的边框切割

self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0);

#12


31  

A lot of the previous answers above are too hacky. They would break at anytime in the future if Apple decides to fix this unexpected behavior.

上面的许多回答都太陈腐了。如果苹果决定修复这一意外的行为,他们将在未来的任何时候暂停。

Root of the issue:

问题的根源:

  1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.

    UITableView不喜欢有高度为0的header。如果你要做的是得到一个高度为0的标头,你可以跳到解。

  2. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.

    即使稍后您将一个非0.0的高度分配给您的头,一个UITableView不喜欢被指定一个高度为0.0的头。

Solution:

解决方案:

Then, the most simple and reliable fix is to ensure that your header height is not 0 when you assign it to your table view.

然后,最简单、最可靠的修复方法是,在将页眉高度赋给表视图时,确保它不是0。

Something like this would work:

类似这样的东西会起作用:

// 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;

Something like this would lead to the issue at some point (typically, after a scroll):

类似这样的事情在某个时候会导致这个问题(通常是在卷轴之后):

// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
self.tableView.tableHeaderView = tableViewHeaderView;

#13


27  

Storyboard:

故事板:

Just uncheck: Adjust Scroll View Insets in View Controller's options

取消勾选:在视图控制器的选项中调整滚动视图内嵌

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

Code:

代码:

self.automaticallyAdjustsScrollViewInsets = false

#14


14  

In my case this was what helped me. I'm supporting ios6 also.

对我来说,这对我有帮助。我支持ios6也。

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

#15


14  

Simply add the following to your viewDidLoad in your VC:

只需在你的VC中添加以下的viewDidLoad:

self.automaticallyAdjustsScrollViewInsets = NO;

#16


13  

This is the solution for iOS 10 using Swift 3:

这是使用Swift 3的ios10的解决方案:

You can get rid of top and bottom paddings by implementing the following methods from the UITableViewDelegate.

通过实现UITableViewDelegate中的以下方法,您可以摆脱顶部和底部的挂件。

    func tableView( _ tableView: UITableView, heightForHeaderInSection section: Int ) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

#17


11  

So I was trying every method here, and this time none of them helped. My case was a grouped table view on iOS 9. I don't really know why and how I found out this one, but for me, setting the tableViewHeader with a UIView with at least 0.01 height worked out. CGRectZero didn't help, nothing really helped:

所以我在这里尝试了所有的方法,这次没有一个有用。我的例子是ios9上的分组表视图。我不知道为什么我发现了这个,但是对我来说,设置一个至少0。01高的UIView的tableViewHeader。CGRectZero没有帮助,没有任何帮助:

tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01))

#18


10  

Swift: iOS I had tableview on scroll view .. when I was click "Back" on the same screen. Scroll view take more space on top.. to solve this I have used :

Swift: iOS我有滚动视图的tableview。当我在同一个屏幕上点击“返回”。滚动视图在顶部占用更多空间。为了解决这个问题,我使用了:

 self.automaticallyAdjustsScrollViewInsets = false

A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets. Default value is true, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to false if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.

一个布尔值,指示视图控制器是否应该自动调整其滚动视图内嵌。默认值为true,该值允许视图控制器根据状态栏、导航栏和工具栏或选项卡栏所使用的屏幕区域调整其滚动视图嵌套。如果您想自己管理滚动视图inset调整,例如当视图层次结构中有多个滚动视图时,将其设置为false。

#19


9  

My answer is going to be more general answer, but can be applied on this as well.

我的答案将是更一般的答案,但也可以应用在这上面。

If the root view (of the ViewController) or the first child (subview) of the root view is subclass of the UIScrollView (or UIScrollView itself), and if

如果视图的根视图(视图控制器)或者是根视图的第一个子视图(子视图)是UIScrollView(或UIScrollView本身)的子类,如果。

self.navigationController.navigationBar.translucent = YES;

framework will automatically set pre-calculated contentInset.

框架将自动设置预计算的contentInset。


To avoid this you can do

要避免这种情况,你可以这么做

self.automaticallyAdjustsScrollViewInsets = NO;

but in my case I wasn't able to do this, because I was implementing SDK which has UIView component which can be used by other developers. That UIView component contains UIWebView (which has UIScrollView as the first subview). If that component is added as the first child in the UIViewController's view hierarchy, automatic insets will be applied by system.

但在我的例子中,我不能这么做,因为我实现了SDK它有UIView组件可以被其他开发者使用。那个UIView组件包含UIWebView(它有UIScrollView作为第一个子视图)。如果该组件作为UIViewController的视图层次结构中的第一个子元素添加,系统将应用自动镶嵌。

I've fixed this by adding dummy view with frame (0,0,0,0) before adding UIWebView.

在添加UIWebView之前,我已经通过添加frame(0,0,0,0)的哑视图来解决了这个问题。

In this case system didn't find subclass of the UIScrollView as the first subview and didn't apply insets

在本例中,系统没有将UIScrollView的子类作为第一个子视图,也没有应用insets

#20


9  

Thanks to the answer by @Aurelien Porte. Here is my solution

感谢@Aurelien Porte的回复。这是我的解决方案

Cause of this issue:-

这个问题的原因:-

  1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.
  2. UITableView不喜欢有高度为0的header。如果你要做的是得到一个高度为0的标头,你可以跳到解。
  3. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.
  4. 即使稍后您将一个非0.0的高度分配给您的头,一个UITableView不喜欢被指定一个高度为0.0的头。

In ViewDidLoad:-

在ViewDidLoad:-

self.edgesForExtendedLayout = UIRectEdge.None

self.automaticallyAdjustsScrollViewInsets = false

No Need For Something Like This :-

不需要这样的东西:-

self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)

In heightForHeaderInSection delegate:-

在heightForHeaderInSection委托:-

if section == 0
    {
        return 1
    }
    else
    {
        return 40; // your other headers height value
    }

In viewForHeaderInSection delegate :-

在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 
}

#21


8  

I'm assuming that is just part of the new UITableViewStyleGrouped styling. It is in all grouped table views and there doesn't seem to be any direct way to control that space.

我假设这只是uitableviewstylegroups样式的一部分。它存在于所有分组的表视图中,而且似乎没有任何直接的方法来控制这个空间。

If that space is being represented by a UIView, it would be possible to search through all the subviews of the UITableView to find that specific view and edit it directly. However, there is also the possibility that that space is just a hardcoded offset before headers and cells start and there won't be any way to edit it.

如果这个空间是由一个UIView表示的,那么可以搜索UITableView的所有子视图来找到那个特定的视图并直接编辑它。但是,也有可能该空间只是头和单元格开始之前的硬编码偏移量,并且没有任何方法编辑它。

To search through all subviews (I would run this code when the table has no cells, to make it a little easier to read the output):

要搜索所有子视图(我将在该表没有单元格时运行此代码,以便更容易读取输出):

- (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];
    }
}

#22


7  

I had the same fix as arielyz. Once I moved the UITableView to be not the first subview of the parent view, it went away. My space was 20 px, not 35.

我和阿里丽兹有同样的安排。一旦我将UITableView移动到父视图的第一个子视图,它就消失了。我的空间是20像素,不是35像素。

I wasn't able to recreate it in a portrait xib, only a landscape xib. I'll file a radar bug later if I can reproduce it in a simple demo app.

我无法在一幅画中重现它,只有一幅风景画。如果我能在一个简单的演示应用程序中复制它,我就会把它归档。

#23


7  

I think making UIEdgeInsets -35 0 0 0 is tedious. In my case, I implemented tableView: heightForHeaderInSection: method and it has a potential to return 0.

我认为制作UIEdgeInsets - 350,0是很乏味的。在我的例子中,我实现了tableView: heightForHeaderInSection:方法,它有可能返回0。

When I changed 0 to 0.1f, the problem just went away.

当我把0变成0。1f时,问题就消失了。

#24


7  

This is how it can be fixed easily in iOS 11 and Xcode 9.1 through Storyboard:

这就是ios11和Xcode 9.1中通过故事板轻松修复的方法:

Select Table View > Size Inspector > Content Insets: Never

选择Table View > Size Inspector > Content Insets: Never

#25


6  

override func viewWillAppear(animated: Bool) {
        self.edgesForExtendedLayout = UIRectEdge.None

 //  OR

self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);

   //OR

 self.automaticallyAdjustsScrollViewInsets = false
        }

#26


5  

use this one i think this help...

用这个,我觉得这个有用……

 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
 {
    return 0.005f;// set this according to that you want...
 }

#27


5  

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{

    return CGFLOAT_MIN;
}

That's all folks!

这是所有人!

#28


4  

I've been banging my head against this one as well. Pretty sure this is an iOS7 bug. What helped me eventually, is the order of views in the xib. I had one view in which table view was displayed correctly, and another in which the table view had that extra 35px space. The only difference between then (UITableView wise), is that in the bad-displaying view UITableView was the first child, whereas in the view which was displaying correctly, it was the second.

我也一直在用我的头撞这个。很肯定这是一个iOS7错误。最终帮助我的是xib中的观点顺序。我有一个视图,在这个视图中,表视图被正确显示,而另一个视图中,表视图有额外的35px空间。唯一的不同之处在于,在坏显示视图UITableView中,UITableView是第一个孩子,而在正确显示的视图中,它是第二个。

That did the trick for me, just changing the order of views. I really prefer not to add extra lines of code for a workaround...

这对我来说很有用,只是改变了视图的顺序。我真的不想为解决方案添加额外的代码行……

#29


4  

The only thing that worked for me was:

对我来说唯一有用的是:

Swift:

迅速:

tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0

Objective-C:

objective - c:

self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 0;

Also, I still had an extra space for the first section. That was because I was using the tableHeaderView property incorrectly. Fixed that as well by adding:

而且,我在第一部分还有额外的空间。那是因为我错误地使用了tableHeaderView属性。通过添加:

self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0.01))

#30


4  

We have multiple answers for this.

我们有很多答案。

1) You can add UIImageview at view didload

1)可以在viewdidload添加UIImageview

UIImageView * imbBackground = [UIImageView new];
[self.view addSubview:imbBackground];

2) You can set header and footer height 0.1

2)可设置页眉和页脚高度0.1

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 0.1;
}

3) You can add header and footer view with height 0.1

3)您可以添加页眉和页脚视图,高度为0.1。

tblCampaigns.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];
tblCampaigns.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];

#1


834  

I was helped by the following:

我得到以下帮助:

YouStoryboard.storyboard > YouViewController > Attributes inspector > Uncheck - Adjust scroll view insets.

YouStoryboard。故事板> YouViewController >属性检查器>取消检查-调整滚动视图内嵌。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

#2


276  

I played around with it a bit more and it seems like this is a side-effect of setting the tableView's tableHeaderView = nil.

我在这里多做了一点,看起来这是设置tableView的tableHeaderView = nil的副作用。

Because my tableView has a dynamically appearing tableHeaderView, when I need to hide the tableHeaderView, instead of doing self.tableView.tableHeaderView = nil;, I do:

因为我的tableView有一个动态显示的tableHeaderView,当我需要隐藏tableHeaderView时,而不是做self。tableView。表头视图= nil;

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];

I like this solution better than setting a somewhat arbitrary contentInset.top because I use the contentInset.top dynamically as well. Having to remember to remove an extra 35px whenever I recalculate contentInset.top is tedious.

我更喜欢这个解决方案,而不是设置一个有点随意的contentInset。top因为我使用了contentInset。高级动态。每当我重新计算contentInset时,必须记住删除一个额外的35px。是乏味的。

#3


168  

For IOS 7 if you are allocing a tableview in a view controller you may look into

对于ios7,如果你在视图控制器中分配一个tableview,你可以查看

self.edgesForExtendedLayout = UIRectEdgeNone;

your problem seemed similar to mine

你的问题和我的相似。

Update:

更新:

Swift in iOS 9.x:

斯威夫特在iOS 9. x:

self.edgesForExtendedLayout = UIRectEdge.None

Swift 3 :

斯威夫特3:

self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)

#4


147  

Try changing the contentInset property that UITableView inherits from UIScrollView.

尝试修改UITableView从UIScrollView继承的contentInset属性。

self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);

It's a workaround, but it works

这是一个变通方案,但它确实有效

#5


125  

self.automaticallyAdjustsScrollViewInsets = NO;

try, you can deal with it!

试试看,你能应付的!

#6


59  

You could detect if your app is running iOS7 or greater and add this two methods in your table view delegate (usually in your UIViewController code)

你可以检测你的应用是否在运行iOS7或更多并在你的表视图委托中添加这两个方法(通常在你的UIViewController代码中)

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

This maybe is not an elegant solution but works for me

这可能不是一个优雅的解决方案,但对我来说是可行的

#7


48  

I have found the cause of my original bug and created a sample project showcasing it. I believe there is an iOS7 bug.

我找到了原始bug的原因,并创建了一个示例项目来展示它。我相信是iOS7有问题。

As of iOS7, if you create a UITableView with the Grouped style, but do not have a delegate set on first layout, then you set a delegate and call reloadData, there will be a 35px space at the top that will never go away.

在iOS7中,如果您使用分组样式创建一个UITableView,但是没有在第一个布局上设置一个委托,那么您就设置一个委托并调用reloadData,在顶部将有一个35px的空间永远不会消失。

See this project I made showcasing the bug: https://github.com/esilverberg/TableViewDelayedDelegateBug

请看我制作的这个项目,它展示了这个bug: https://github.com/esilverberg/TableViewDelayedDelegateBug

Specifically this file: https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

特别是这个文件:https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

If line 24 is active,

如果第24行是活动的,

[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];

there will be an extra 35 px space at the top. If line 27 is active and 24 is commented out,

顶部将有一个额外的35像素空间。如果第27行是活动的,第24行被注释掉,

self.tableView.delegate = self;

no space at the top. It's like the tableView is caching a result somewhere and not redrawing itself after the delegate is set and reloadData is called.

顶部没有空间。就像tableView会缓存一个结果,而不会在设置委托并调用reloadData之后重新绘制自己。

#8


45  

Uncheck "Adjust Scroll View insets"

取消“调整滚动视图嵌套”

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

#9


44  

Another quick comment... even in XCode 6.1, there is a bug with vertical spaces appearing at the top of UIScrollViews, UITextViews and UITableViews.

另一个快速评论……即使在XCode 6.1中,在UIScrollViews、UITextViews和UITableViews的顶部也出现了垂直空格的bug。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

Sometimes, the only way to fix this issue is to go into the Storyboard and drag the problem control so it's no longer the first subview on the page.

有时,解决这个问题的唯一方法是进入故事板并拖动问题控件,这样它就不再是页面上的第一个子视图。

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

(My thanks to Oded for pointing me in this direction... I'm posting this comment, just to add a few screenshots, to demonstrate the symptoms and fix.)

(感谢Oded指正我的方向……)我发布这条评论,只是为了添加一些截图,以展示症状和修复。

#10


37  

According to this transition guide for iOS7 by Apple, the scroll view’s content insets is automatically adjusted. The default value of automaticallyAdjustsScrollViewInsets is set to YES.

根据苹果iOS7的转换指南,滚动视图的内容会自动调整。automaticallycontrollsscrollviewinsets的默认值设置为YES。

The UIViewController which has the UITableView should set this property to NO.

拥有UITableView的UIViewController应该将这个属性设置为NO。

self.automaticallyAdjustsScrollViewInsets = NO;

This will do the trick.

这样就可以了。

EDIT 1:

编辑1:

Also, one could try -

还有,我们可以试试-

self.navigationController.navigationBar.translucent = YES;

This also removes the extra padding on the top.

这也消除了顶部的额外填充。

#11


35  

While using grouped TableView use this to avoid border cutting in viewWillAppear

使用分组的TableView时,可以使用它来避免viewWillAppear中的边框切割

self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0);

#12


31  

A lot of the previous answers above are too hacky. They would break at anytime in the future if Apple decides to fix this unexpected behavior.

上面的许多回答都太陈腐了。如果苹果决定修复这一意外的行为,他们将在未来的任何时候暂停。

Root of the issue:

问题的根源:

  1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.

    UITableView不喜欢有高度为0的header。如果你要做的是得到一个高度为0的标头,你可以跳到解。

  2. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.

    即使稍后您将一个非0.0的高度分配给您的头,一个UITableView不喜欢被指定一个高度为0.0的头。

Solution:

解决方案:

Then, the most simple and reliable fix is to ensure that your header height is not 0 when you assign it to your table view.

然后,最简单、最可靠的修复方法是,在将页眉高度赋给表视图时,确保它不是0。

Something like this would work:

类似这样的东西会起作用:

// 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;

Something like this would lead to the issue at some point (typically, after a scroll):

类似这样的事情在某个时候会导致这个问题(通常是在卷轴之后):

// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
self.tableView.tableHeaderView = tableViewHeaderView;

#13


27  

Storyboard:

故事板:

Just uncheck: Adjust Scroll View Insets in View Controller's options

取消勾选:在视图控制器的选项中调整滚动视图内嵌

为什么在我的UITableView顶部有额外的填充,并且在iOS7中有uitableviewstylegroups

Code:

代码:

self.automaticallyAdjustsScrollViewInsets = false

#14


14  

In my case this was what helped me. I'm supporting ios6 also.

对我来说,这对我有帮助。我支持ios6也。

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

#15


14  

Simply add the following to your viewDidLoad in your VC:

只需在你的VC中添加以下的viewDidLoad:

self.automaticallyAdjustsScrollViewInsets = NO;

#16


13  

This is the solution for iOS 10 using Swift 3:

这是使用Swift 3的ios10的解决方案:

You can get rid of top and bottom paddings by implementing the following methods from the UITableViewDelegate.

通过实现UITableViewDelegate中的以下方法,您可以摆脱顶部和底部的挂件。

    func tableView( _ tableView: UITableView, heightForHeaderInSection section: Int ) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

#17


11  

So I was trying every method here, and this time none of them helped. My case was a grouped table view on iOS 9. I don't really know why and how I found out this one, but for me, setting the tableViewHeader with a UIView with at least 0.01 height worked out. CGRectZero didn't help, nothing really helped:

所以我在这里尝试了所有的方法,这次没有一个有用。我的例子是ios9上的分组表视图。我不知道为什么我发现了这个,但是对我来说,设置一个至少0。01高的UIView的tableViewHeader。CGRectZero没有帮助,没有任何帮助:

tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01))

#18


10  

Swift: iOS I had tableview on scroll view .. when I was click "Back" on the same screen. Scroll view take more space on top.. to solve this I have used :

Swift: iOS我有滚动视图的tableview。当我在同一个屏幕上点击“返回”。滚动视图在顶部占用更多空间。为了解决这个问题,我使用了:

 self.automaticallyAdjustsScrollViewInsets = false

A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets. Default value is true, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to false if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.

一个布尔值,指示视图控制器是否应该自动调整其滚动视图内嵌。默认值为true,该值允许视图控制器根据状态栏、导航栏和工具栏或选项卡栏所使用的屏幕区域调整其滚动视图嵌套。如果您想自己管理滚动视图inset调整,例如当视图层次结构中有多个滚动视图时,将其设置为false。

#19


9  

My answer is going to be more general answer, but can be applied on this as well.

我的答案将是更一般的答案,但也可以应用在这上面。

If the root view (of the ViewController) or the first child (subview) of the root view is subclass of the UIScrollView (or UIScrollView itself), and if

如果视图的根视图(视图控制器)或者是根视图的第一个子视图(子视图)是UIScrollView(或UIScrollView本身)的子类,如果。

self.navigationController.navigationBar.translucent = YES;

framework will automatically set pre-calculated contentInset.

框架将自动设置预计算的contentInset。


To avoid this you can do

要避免这种情况,你可以这么做

self.automaticallyAdjustsScrollViewInsets = NO;

but in my case I wasn't able to do this, because I was implementing SDK which has UIView component which can be used by other developers. That UIView component contains UIWebView (which has UIScrollView as the first subview). If that component is added as the first child in the UIViewController's view hierarchy, automatic insets will be applied by system.

但在我的例子中,我不能这么做,因为我实现了SDK它有UIView组件可以被其他开发者使用。那个UIView组件包含UIWebView(它有UIScrollView作为第一个子视图)。如果该组件作为UIViewController的视图层次结构中的第一个子元素添加,系统将应用自动镶嵌。

I've fixed this by adding dummy view with frame (0,0,0,0) before adding UIWebView.

在添加UIWebView之前,我已经通过添加frame(0,0,0,0)的哑视图来解决了这个问题。

In this case system didn't find subclass of the UIScrollView as the first subview and didn't apply insets

在本例中,系统没有将UIScrollView的子类作为第一个子视图,也没有应用insets

#20


9  

Thanks to the answer by @Aurelien Porte. Here is my solution

感谢@Aurelien Porte的回复。这是我的解决方案

Cause of this issue:-

这个问题的原因:-

  1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.
  2. UITableView不喜欢有高度为0的header。如果你要做的是得到一个高度为0的标头,你可以跳到解。
  3. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.
  4. 即使稍后您将一个非0.0的高度分配给您的头,一个UITableView不喜欢被指定一个高度为0.0的头。

In ViewDidLoad:-

在ViewDidLoad:-

self.edgesForExtendedLayout = UIRectEdge.None

self.automaticallyAdjustsScrollViewInsets = false

No Need For Something Like This :-

不需要这样的东西:-

self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)

In heightForHeaderInSection delegate:-

在heightForHeaderInSection委托:-

if section == 0
    {
        return 1
    }
    else
    {
        return 40; // your other headers height value
    }

In viewForHeaderInSection delegate :-

在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 
}

#21


8  

I'm assuming that is just part of the new UITableViewStyleGrouped styling. It is in all grouped table views and there doesn't seem to be any direct way to control that space.

我假设这只是uitableviewstylegroups样式的一部分。它存在于所有分组的表视图中,而且似乎没有任何直接的方法来控制这个空间。

If that space is being represented by a UIView, it would be possible to search through all the subviews of the UITableView to find that specific view and edit it directly. However, there is also the possibility that that space is just a hardcoded offset before headers and cells start and there won't be any way to edit it.

如果这个空间是由一个UIView表示的,那么可以搜索UITableView的所有子视图来找到那个特定的视图并直接编辑它。但是,也有可能该空间只是头和单元格开始之前的硬编码偏移量,并且没有任何方法编辑它。

To search through all subviews (I would run this code when the table has no cells, to make it a little easier to read the output):

要搜索所有子视图(我将在该表没有单元格时运行此代码,以便更容易读取输出):

- (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];
    }
}

#22


7  

I had the same fix as arielyz. Once I moved the UITableView to be not the first subview of the parent view, it went away. My space was 20 px, not 35.

我和阿里丽兹有同样的安排。一旦我将UITableView移动到父视图的第一个子视图,它就消失了。我的空间是20像素,不是35像素。

I wasn't able to recreate it in a portrait xib, only a landscape xib. I'll file a radar bug later if I can reproduce it in a simple demo app.

我无法在一幅画中重现它,只有一幅风景画。如果我能在一个简单的演示应用程序中复制它,我就会把它归档。

#23


7  

I think making UIEdgeInsets -35 0 0 0 is tedious. In my case, I implemented tableView: heightForHeaderInSection: method and it has a potential to return 0.

我认为制作UIEdgeInsets - 350,0是很乏味的。在我的例子中,我实现了tableView: heightForHeaderInSection:方法,它有可能返回0。

When I changed 0 to 0.1f, the problem just went away.

当我把0变成0。1f时,问题就消失了。

#24


7  

This is how it can be fixed easily in iOS 11 and Xcode 9.1 through Storyboard:

这就是ios11和Xcode 9.1中通过故事板轻松修复的方法:

Select Table View > Size Inspector > Content Insets: Never

选择Table View > Size Inspector > Content Insets: Never

#25


6  

override func viewWillAppear(animated: Bool) {
        self.edgesForExtendedLayout = UIRectEdge.None

 //  OR

self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);

   //OR

 self.automaticallyAdjustsScrollViewInsets = false
        }

#26


5  

use this one i think this help...

用这个,我觉得这个有用……

 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
 {
    return 0.005f;// set this according to that you want...
 }

#27


5  

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{

    return CGFLOAT_MIN;
}

That's all folks!

这是所有人!

#28


4  

I've been banging my head against this one as well. Pretty sure this is an iOS7 bug. What helped me eventually, is the order of views in the xib. I had one view in which table view was displayed correctly, and another in which the table view had that extra 35px space. The only difference between then (UITableView wise), is that in the bad-displaying view UITableView was the first child, whereas in the view which was displaying correctly, it was the second.

我也一直在用我的头撞这个。很肯定这是一个iOS7错误。最终帮助我的是xib中的观点顺序。我有一个视图,在这个视图中,表视图被正确显示,而另一个视图中,表视图有额外的35px空间。唯一的不同之处在于,在坏显示视图UITableView中,UITableView是第一个孩子,而在正确显示的视图中,它是第二个。

That did the trick for me, just changing the order of views. I really prefer not to add extra lines of code for a workaround...

这对我来说很有用,只是改变了视图的顺序。我真的不想为解决方案添加额外的代码行……

#29


4  

The only thing that worked for me was:

对我来说唯一有用的是:

Swift:

迅速:

tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0

Objective-C:

objective - c:

self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 0;

Also, I still had an extra space for the first section. That was because I was using the tableHeaderView property incorrectly. Fixed that as well by adding:

而且,我在第一部分还有额外的空间。那是因为我错误地使用了tableHeaderView属性。通过添加:

self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0.01))

#30


4  

We have multiple answers for this.

我们有很多答案。

1) You can add UIImageview at view didload

1)可以在viewdidload添加UIImageview

UIImageView * imbBackground = [UIImageView new];
[self.view addSubview:imbBackground];

2) You can set header and footer height 0.1

2)可设置页眉和页脚高度0.1

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 0.1;
}

3) You can add header and footer view with height 0.1

3)您可以添加页眉和页脚视图,高度为0.1。

tblCampaigns.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];
tblCampaigns.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];