为什么我的UITableView顶部有额外的填充,iOS7中的样式为UITableViewStyleGrouped

sut 发布于 2019-04-05 ios 最后更新 2019-04-05 13:10 205 浏览

从iOS7开始,我的UITableView顶部有额外的空间,其样式为UITableViewStyleGrouped。 这里是一个例子:

enter image description here tableview从第一个箭头开始,有35个像素的原因不明的填充,然后绿色标题是由viewForHeaderInSection(其中部分为0)返回的UIView。 任何人都可以解释这35像素量来自哪里,以及如何在不切换到UITableViewStylePlain的情况下摆脱它?
已邀请:

nvelit

赞同来自:

我的答案将是更一般的答案,但也可以应用于此。 如果根视图(ViewController)或根视图的第一个子视图(子视图)是UIScrollView(或UIScrollView本身)的子类,如果

self.navigationController.navigationBar.translucent = YES;
框架将自动设置预先计算的contentInset。
为了避免这种情况你可以做到
self.automaticallyAdjustsScrollViewInsets = NO;
但在我的情况下,我无法做到这一点,因为我正在实现具有UIView组件的SDK,可供其他开发人员使用。该UIView组件包含UIWebView(其中UIScrollView作为第一个子视图)。如果将该组件添加为UIViewController视图层次结构中的第一个子组件,则系统将应用自动插入。 我在添加UIWebView之前通过添加带有框架(0,0,0,0)的虚拟视图来修复此问题。 在这种情况下,系统没有找到UIScrollView的子类作为第一个子视图,并且没有应用insets

znemo

赞同来自:

根据Apple的transition guide for iOS7,滚动视图的内容插入会自动调整。 automaticAdjustsScrollViewInsets的默认值设置为YES。 具有UITableView的UIViewController应将此属性设置为NO。

self.automaticallyAdjustsScrollViewInsets = NO;
这样就可以了。 编辑1: 也可以试试 -
self.navigationController.navigationBar.translucent = YES;
这也消除了顶部的额外填充。

xet

赞同来自:

使用这个我认为这有帮助...

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

zomnis

赞同来自:

只需在视图的绝对顶部固定您的tableview(或使其开始)。额外的不需要的空间正好是导航栏的高度。

fearum

赞同来自:

感谢@Aurelien Porte的回答。这是我的解决方案 这个问题的原因: -

  1. UITableView不喜欢高度为0.0的标题。如果你要做的是拥有一个高度为0的标题,你可以跳到解决方案。
  2. 即使稍后您为标题指定了非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 
}

ysequi

赞同来自:

以下是我的帮助: YouStoryboard.storyboard> YouViewController>属性检查器>取消选中 - 调整滚动视图插入。 enter image description here

siusto

赞同来自:

我和arielyz有同样的解决方法。一旦我将UITableView移动到不是父视图的第一个子视图,它就消失了。我的空间是20像素,而不是35像素。 我无法在肖像xib中重新创建它,只有一个风景xib。如果我可以在一个简单的演示应用程序中重现它,我将在稍后提交雷达错误。

xsed

赞同来自:

确保您已为表格提供约束。我没有并且遇到类似的问题,即在桌子底部有一个无法解释的填充物。

oqui

赞同来自:

我不确定这个好的答案是否适用于我 我选择表视图,导航到标尺,将Y值更改为零 enter image description here

hquas

赞同来自:

所以我在这里尝试各种方法,而这次没有一个方法有帮助。我的案例是在iOS 9上的分组表格视图。我真的不知道为什么以及如何找到这个,但对我来说,设置tableViewHeaderUIView至少0.01高度。 CGRectZero没有帮助,没有任何帮助:

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

liste

赞同来自:

Swift:iOS我在滚动视图上有tableview ..当我在同一个屏幕上点击“Back”时。滚动视图在顶部占用更多空间..解决这个我用过:

 self.automaticallyAdjustsScrollViewInsets = false
一个布尔值,指示视图控制器是否应自动调整其滚动视图插入。 默认值为true,允许视图控制器调整其滚动视图插入以响应状态栏,导航栏和工具栏或选项卡栏消耗的屏幕区域。如果要自己管理滚动视图插入调整,则设置为false,例如视图层次结构中有多个滚动视图时。

pullam

赞同来自:

就我而言,这对我有所帮助。我也支持ios6。

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

but

赞同来自:

我经历了所有的答案。没有人为我工作。我所要做的就是:

self.myTableView.rowHeight = UITableViewAutomaticDimension
self.myTableView.estimatedRowHeight = 44.0
此外,问题没有发生在tableView的顶部。它发生在tableView的每个部分的顶部。 FWIW这个问题只发生在iOS9上。我们的应用程序适用于iOS10和iOS 11。 我强烈建议你看看这个很棒的问题及其最佳答案: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

eea

赞同来自:

尝试更改UITableViewUIScrollView继承的contentInset属性。

self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);
这是一种解决方法,但它确实有效

kaut

赞同来自:

这是通过Storyboard在iOS 11和Xcode 9.1中轻松修复的方法: 选择“表视图”>“大小检查器”>“内容插入:从不”

hiure

赞同来自:

在iOS 7中,您可以查看屏幕的内容,而不是在navBar下方。它很容易设置到你导航栏的底部。检查解决方案的THIS答案,它不是同一个问题,但与您的问题非常相关。

xnobis

赞同来自:

故事板: 确保您的UITableView顶部约束不会显示“在顶部布局指南下”。相反它应该说“顶级空间:Superview”(Superview.Top)。 当然,在包含UITableView的UIViewController中,取消选中“Adjust Scroll View Insets”。

tut

赞同来自:

override func viewWillAppear(animated: Bool) {
        self.edgesForExtendedLayout = UIRectEdge.None
//  OR
self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
//OR
self.automaticallyAdjustsScrollViewInsets = false
        }

frem

赞同来自:

如果选择UITableViewStyleGrouped的样式,则需要实现HeaderFooter高度委托方法,并且返回值需要大于0;喜欢这个:

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

lqui

赞同来自:

投入我的十美分 - 我从桌面视图中删除了标题单元后出现了同样的问题。为了解决这个问题,我将Attributes Inspector中的TableView Style从“Grouped”更改为“Plain”,并删除了额外的空格。

xipsam

赞同来自:

下面的操作(Swift)解决了这个问题,但是当你不需要标题时这可以解决。

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return CGFloat.min
}
如果你这样做,你将不得不放弃第一部分并使用其他内容。 UITableViewDataSource实施:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return <number_of_data_sections>+1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // the first section we don't use for data
    if section == 0 {
        return 0
    }
// starting from 1, there are sections we use
    if section == 1 { 
        let dataSection = section - 1
// use dataSection for your content (useful, when data provided by fetched result controller). For example:
       if let sectionInfo = myFRC!.sections![dataSection] as? NSFetchedResultsSectionInfo {
            return sectionInfo.numberOfObjects
        }
    }
return 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let dataIndexPath = NSIndexPath(forRow: indexPath.row, inSection: (indexPath.section - 1) )
    // return cell using transformed dataIndexPath
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 1 {
        // return your header height
    }
    return CGFloat.min
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if section == 1 {
        // return your header view
    }
    return nil
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    // in my case, even when 1st section header was of zero heigh, I saw the space, an that was a footer. I did not need footer at all, so always gave zero height
    return CGFloat.min
}
就是这样。模型对变化一无所知,因为我们在访问数据时会转换节号。

ueaque

赞同来自:

取消选中“调整滚动视图插入内容” enter image description here

iid

赞同来自:

使用分组TableView时,使用此方法可以避免在viewWillAppear中进行边框切割

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

lsunt

赞同来自:

对于IOS 7,如果要在视图控制器中分配tableview,可以查看

self.edgesForExtendedLayout = UIRectEdgeNone;
你的问题似乎与我的相似 更新: iOS 9.x中的Swift:
self.edgesForExtendedLayout = UIRectEdge.None
斯威夫特3:
self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)

gminus

赞同来自:

我玩了一下它似乎这是设置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是单调乏味的。

est_et

赞同来自:

之前的答案都不适合我。最终为我的情况工作的是什么(在向我的Table View动态添加标题后看到填充)是从Document Outline中选择Navigation Bar并重新检查Translucent框(与一些强制它为半透明的答案相反) 。我之前没有选中它,因为它使我的红色看起来有点橙色,但我无法尝试重新排序场景中元素的解决方案,因为Table View是此场景中唯一的元素。只要您对Navigation Bar的颜色在其上方具有半透明层,您就可以使用此解决方案。希望这可以帮助 :)

eea

赞同来自:

我假设这只是新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];
    }
}

snihil

赞同来自:

我找到了原始bug的原因并创建了一个展示它的示例项目。我相信有一个iOS7错误。 从iOS7开始,如果您使用Grouped样式创建UITableView,但在第一个布局上没有设置委托,那么您设置委托并调用reloadData,顶部将有一个35px空间永远不会消失。 看到我做的这个项目展示了错误:https://github.com/esilverberg/TableViewDelayedDelegateBug 特别是这个文件:https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m 如果第24行有效,

[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];
顶部会有额外的35像素空间。如果第27行处于活动状态且24被注释掉,
self.tableView.delegate = self;
顶部没有空间。这就像tableView在某处缓存结果而在设置委托并调用reloadData后不重绘自身。

jiusto

赞同来自:

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

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}
这可能不是一个优雅的解决方案,但对我有用

sit_in

赞同来自:

唯一对我有用的是: 迅速:

tableView.sectionHeaderHeight = 0
tableView.sectionFooterHeight = 0
Objective-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))

ererum

赞同来自:

我们有多个答案。 1)您可以在view didload中添加UIImageview

UIImageView * imbBackground = [UIImageView new];
[self.view addSubview:imbBackground];
2)您可以设置页眉和页脚高度0.1
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 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)];

vsit

赞同来自:

self.automaticallyAdjustsScrollViewInsets = NO;
试试,你可以处理它!

bdicta

赞同来自:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return CGFLOAT_MIN;
}
这就是所有人!

lenim

赞同来自:

故事板: 只需取消选中:View Controller的选项中的Adjust Scroll View Insets

enter image description here 码:
self.automaticallyAdjustsScrollViewInsets = false

hquae

赞同来自:

这样做的另一种方式......但我喜欢它,因为它避免了硬编码任何高度值。 在UITableViewStyleGrouped表(静态或动态)中,只需在tableView(_:heightForHeaderInSection)中指定所需的高度。我正在根据节标题标签的底部填充计算新的高度。

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
var height = UITableViewAutomaticDimension
if section == 0, let header = tableView.headerViewForSection(section) {
        if let label = header.textLabel {
            // get padding below label
            let bottomPadding = header.frame.height - label.frame.origin.y - label.frame.height
            // use it as top padding
            height = label.frame.height + (2 * bottomPadding)
        }
    }
return height
}
在iOS 9,Xcode 7.3上测试。 希望能帮助到你。

aut_ut

赞同来自:

我有一个带有Container的VC(btw是Nav控制器的一部分),并且嵌入了一个TableVC。 选择我的TableVC,查看属性面板:

  • 取消选中自动调整滚动插图
  • 取消选中顶栏下的延伸边
然后我将Container的autoconstraint设置为相对于父视图: Container View.top = ParentView.Top Margin 这为我完成了以下事项:
  • 将桌子拉到顶部,但在我的导航栏下方
  • 刷新后,表格返回到此位置,而不是正常情况下导航栏下方的<+
  • 滚动桌子底部的底部,而不是它
这个设置对我来说有很多反复试验,但我最终发现了lekksi @ Remove empty space before cells in UITableView发布的这些小细节

jsed

赞同来自:

只需将以下内容添加到VC中的viewDidLoad:

self.automaticallyAdjustsScrollViewInsets = NO;

gest

赞同来自:

以上很多以前的答案太过于苛刻。如果Apple决定解决这种意外行为,他们将来会随时休息。 问题的根源:

  1. UITableView不喜欢高度为0.0的标题。如果你要做的是拥有一个高度为0的标题,你可以跳到解决方案。
  2. 即使稍后您为标题指定了非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;

nrerum

赞同来自:

我注意到这个问题有很多答案取决于你想要做什么,所以我会分享我的,以防任何人想要得到同样的效果:

enter image description here 在我的视图控制器中,我有一个分组UITableView,其tableHeaderView由一个200磅高的UIScrollView和一个属性UILabel组成,其中包含广告标题,价格,位置和发布的时间。下面是表格视图的内容。 使用分组表视图标题的默认尺寸,“MORE INFO”标题远低于“5天前”标签。我通过覆盖每个部分的页眉和页脚的高度来修复它(已经是上面的图像)。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return section == kMoreInfoSection ? 33 : UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return UITableViewAutomaticDimension;
}
我从接受过的答案中了解了@ erurainon评论的高度,以及来自https://stackoverflow.com/a/14404104/855680UITableViewAutomaticDimension。我不需要在视图控制器中将self.automaticallyAdjustsScrollViewInsets设置为NO,这与接受的答案所暗示的不同。 我也尝试过设置UIEdgeInsets并为表格视图提供顶部的负值,但它不起作用 - 整个表格视图向上移动,包括tableHeaderView

xnemo

赞同来自:

这是使用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
    }

gquia

赞同来自:

在我的情况下,在Storyboard中的原型可视化中有一个名为“HeaderView”的不需要的单元格,当我删除它时一切都很好。

nnam

赞同来自:

我刚刚从Interface Builder中删除了UITableView,再次创建它并且奇怪的35px消失了。 似乎Interface Builder中存在一个奇怪的错误。

tquod

赞同来自:

我也一直在反对这一个。很确定这是一个iOS7错误。 最终帮助我的是xib中的视图顺序。我有一个视图正确显示表视图,另一个视图具有额外的35px空间。那时(UITableView明智)之间的唯一区别是,在显示不良的视图中,UITableView是第一个子节点,而在正确显示的视图中,它是第二个。 这对我来说只是改变了观点的顺序。我真的不想为解决方法添加额外的代码行...

fearum

赞同来自:

我认为制作UIEdgeInsets -35 0 0 0是乏味的。在我的例子中,我实现了tableView:heightForHeaderInSection:方法,它有可能返回0。 当我将0改为0.1f时,问题就消失了。

killo

赞同来自:

另一个快速评论......即使在XCode 6.1中,也有一个错误,垂直空格出现在UIScrollViewsUITextViewsUITableViews的顶部。

enter image description here 有时,解决此问题的唯一方法是进入故事板并拖动问题控件,使其不再是页面上的第一个子视图。 enter image description here (感谢Oded指点我这个方向......我发布这个评论,只是为了添加一些截图,以展示症状和修复。)