从iOS7开始,在我的UITableView顶部有额外的空间它有一个UITableViewStyleGrouped样式。
这里有一个例子:
tableview从第一个箭头开始,有35个像素的无法解释的填充,然后绿色的头是一个由viewForHeaderInSection返回的UIView(其中section为0)。
有人能解释一下这个35像素的数量是从哪里来的吗?我如何才能在不切换到UITableViewStylePlain的情况下摆脱它?
更新(回答):
在iOS 11及更高版本中:
tableView.contentInsetAdjustmentBehavior = .never
感谢@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)
在highforheaderinsection委托中:-
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
}
我已经找到了我最初的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调用后重新绘制自己。
下面的操作(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
}
就是这样。模型不知道任何变化,因为我们在访问数据时转换了节号。
我注意到这个问题有很多答案,这取决于你想要做什么,所以我将分享我的答案,以防有人想要同样的效果:
在我的视图控制器中,我有一个分组的UITableView,它的tableHeaderView由一个200点高的UIScrollView和一个单独的带有属性的UILabel组成,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/855680了解了UITableViewAutomaticDimension。我不需要设置self。automyadjustsscrollviewinsets在我的视图控制器中不像接受的答案所建议的那样为NO。
我也已经尝试设置UIEdgeInsets和给表视图一个负值的顶部,但它没有工作-整个表视图移动,包括tableHeaderView。