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

这里有一个例子:

tableview从第一个箭头开始,有35个像素的无法解释的填充,然后绿色的头是一个由viewForHeaderInSection返回的UIView(其中section为0)。

有人能解释一下这个35像素的数量是从哪里来的吗?我如何才能在不切换到UITableViewStylePlain的情况下摆脱它?


更新(回答):

在iOS 11及更高版本中:

tableView.contentInsetAdjustmentBehavior = .never

当前回答

我已经找到了我最初的bug的原因,并创建了一个示例项目来展示它。我相信有一个iOS7漏洞。

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

看这个项目我做的展示bug: 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];

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

self.tableView.delegate = self;

顶部没有空间。这就像tableView在某处缓存结果而不是在委托设置和reloadData调用后重新绘制自己。

其他回答

None of the previous answers worked for me. What did end up working for my situation (which was seeing that padding after dynamically adding a header to my Table View) was selecting the Navigation Bar from the Document Outline and rechecking the Translucent box (contrary to some answers that were saying to force it to be translucent). I had previously unchecked it because it had made my red look a little orange, but I could not try the solution of reordering the elements in the scene since the Table View was the only element in this scene. This solution works as long as you are okay with the Navigation Bar's color having a translucent layer over it. Hope this helps :)

设置内容插入到从来没有解决我的问题。

根据苹果的文档:

当将视图分配给此属性时,将该视图的高度设置为 一个非零值。表视图只尊重您的高度 视图的框架矩形;它调整你的头视图的宽度 自动匹配表视图的宽度。

斯威夫特5

如果你有一个分组UITableView,你想要一个tableHeaderView:

在将视图分配给tableView之前。tableHeaderView,设置该视图的高度为一个非零值,例如:

// Set the initial height of your custom view to the smallest value  
myTableHeaderView.frame.size.height = .leastNonzeroMagnitude

// Assign your custom view to the header view
tableView.tableHeaderView = myTableHeaderView

// Set width constraint, height should grow based on your view. 
tableView.tableHeaderView!.widthAnchor.constraint(equalTo: tableView.widthAnchor).isActive = true

不需要使用contentInsets或处理委托方法。

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

这对我很管用。也可以根据section给出标题的高度。

下面的操作(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
}

就是这样。模型不知道任何变化,因为我们在访问数据时转换了节号。