UITableView节标题自动高度未正确更新

问题描述:

我遇到了包含UILabel的自动/动态UITableView节标题视图的问题(numberOfLines = 0)。高度计算不正确,特别是一旦您滚动表格并重新使用视图。有时,UILabel包装,有时会被截断,有时一个或多个标签不可见,有时标签之间会有额外的间距。自定义视图包含一个包含三个UILabels的垂直UIStackView,一次包装。UITableView节标题自动高度未正确更新

展示此问题的完整示例应用程序可在https://github.com/outerstorm/tableviewHeaderTest找到。

节头的高度设置为自动在viewDidLoad中有以下内容:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension 
    tableView.estimatedSectionHeaderHeight = 30.0 

,并已实现了以下heightForHeaderInSection只是设法得到它的工作:

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

我有还尝试致电setNeedsLayout()layoutIfNeeded()在各个点无济于事。任何建议将不胜感激。

下面是在应用程序中看到的行为的屏幕截图。第一部分是截止,第二部分是太高:

enter image description here

一般

heightForHeaderInSection 

使用UITableViewAutomaticDimension时前

viewForHeaderInSection 

总是叫,sectionheader高度将只计算一次手动调用tableview.reloadData()。

在代码中,您每次都会更改sectionheader文本。高度在第一时间计算,并且不会自动改变。

,您可以更改设置FUNC按键:

func setup(someNum: Int) { 

    let text = String(repeating: "This is where the really long text goes so that it will wrap lines appropriately", count: someNum) 

    mainLabel.text = text 
} 

和部分指标传递给我最近都面临着这样的问题的功能

+0

这不符合虚拟化。这些单元已经排队,每次发生时都必须重新调整大小。如果没有,那么虚拟化被破坏。 – Tim

我解决它通过设置多标签preferredMaxLayoutWidth,即

之前在标签中设置值,设置其preferredMaxLayoutWidth为:

self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width 
self.label2.preferredMaxLayoutWidth = self.label2.frame.size.width 
self.label3.preferredMaxLayoutWidth = self.label3.frame.size.width 
+0

我试过这个,并没有看到任何行为改变。这个问题仍然存在于示例应用程序中。 – outerstorm

只需添加estimatedHeightForHeaderInSection功能和回报您预测的高度。它会解决你的问题。从here

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat 
{ 
    return 30; 
} 
+0

我没有看到有或没有这种行为的任何变化。 – outerstorm

+0

它似乎工作正常,没有任何问题,我在10.3.2。你的ios版本是什么? –

+0

也10.3.2。我使用示例应用程序的行为以屏幕截图更新了问题。此外,该示例应用程序在github上进行了更新,并带有建议的修复程序。 – outerstorm

一种解决方法下载修改后的项目可保持在阵列头的意见,然后从预测的高度方法返回的视图高度

for _ in 0 ..< data.count { 

     let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeaderView") as! CustomHeaderView 
     view.setup() 
     headerViews.append(view) 
    } 


func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat 
{ 
    let view = headerViews[section] as? UIView 
    return (view?.frame.size.height)! 
} 

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 

    return headerViews[section] as? UIView 
} 
+0

虽然这可能会起作用,但它会导致虚拟化。这就像使用tableviews的原因的50%! – Tim

添加self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width self.label1.numberoflines = 0; self.label1.linebreakmode = NSLineBreakByWordWrapping; 在awakeFromNib方法 或 请检查一次https://github.com/krishnasolankiD/multiLineLabel