Ios UITableView自调整单元格大小/节头重新加载UI错误
很多时候,当我重新加载数据,重新加载某些特定的节/行时,我都会遇到单元格/节标题“闪烁的问题。如果只显示项目,则所有内容都具有正确的框架。但是当我需要重新加载它们时,错误就会出现 当我用硬编码的值表示单元格的高度或截面的高度时,这个错误就消失了 这是密码Ios UITableView自调整单元格大小/节头重新加载UI错误,ios,swift,xcode,uitableview,Ios,Swift,Xcode,Uitableview,很多时候,当我重新加载数据,重新加载某些特定的节/行时,我都会遇到单元格/节标题“闪烁的问题。如果只显示项目,则所有内容都具有正确的框架。但是当我需要重新加载它们时,错误就会出现 当我用硬编码的值表示单元格的高度或截面的高度时,这个错误就消失了 这是密码 self.tableView.rowHeight = UITableViewAutomaticDimension self.tableView.sectionHeaderHeight = UITableViewAutomaticDimensio
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 40
self.tableView.estimatedSectionHeaderHeight = 40
节和行本身都有正确的约束。然后,当我需要更新单元格时,我尝试调用reloadCell
,reloadSection
和reloadData
。每个方法都会产生一个闪烁的问题。这是gif-
有两个问题:
注意:每次单击单元格时,我都调用reloadData()
。几乎可以肯定这没什么大不了的,因为它与任何更新内容的方式都不兼容
1。当你向下滚动并单击某个单元格时,它会向上滚动一点。我还发现它滚动到的位置取决于estimatedHeight
值。有人能解释一下UITableView是如何使用这些值的吗?确切地说,它根据估计值设置contentSize,以及何时以及如何将自身重新加载到最终内容大小
2.我添加了beginUpdate()
和endUpdates()
来向您显示每次调用reloadData()
时发生的节头闪烁的错误
这些是已知的iOS bug吗?因为他们看起来真的很好。我有正确的约束,我不做任何自定义操作。当我设置硬编码值并以通常的heightFor…
方法返回它们时,一切看起来都很好。但由于自调整单元格大小是本机功能,我希望最终至少使用一次,而不会出现任何UI问题:)
更新:
对代码的一些补充:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let (section, preference) = self.sectionPreferenceFor(indexPath: indexPath)
if section.type == .Multiple {
preference.selected = !preference.selected
} else {
(section.items!.array as! [Preference])!.forEach({ $0.selected = false })
preference.selected = true
}
tableView.reloadData()
}
为了显示bug#2,我刚刚将tableView.reloadData()
包装为beginUpdates()
和endUpdates()
以下是我在viewDidLoad()中看到的内容:
而且,通常在行/节的配置中没有什么特殊之处
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: String.init(describing: PreferenceMessageSectionHeaderView.self)) as?PreferenceMessageSectionHeaderView
view?.configureWith(message: self.headerMessage)
return view
} else {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: String.init(describing: PreferenceSectionHeaderView.self)) as? PreferenceSectionHeaderView
view?.configureWith(title: section.name)
return view
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let (section, preference) = self.sectionPreferenceFor(indexPath: indexPath)
if section.type == .Single {
let cell = tableView.dequeueReusableCell(withIdentifier: String.init(describing: RadioButtonCell.self)) as! RadioButtonCell
cell.configureWith(title: preference.name, selected: preference.selected)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: String.init(describing: CheckBoxCell.self)) as! CheckBoxCell
cell.configureWith(title: preference.name, selected: preference.selected)
return cell
}
}
你能展示你剩下的代码吗?@aaqibhussan当然。我更新了帖子。你是不是直接访问自定义单元格对象而不是重新加载tableView来尝试的?@AaqibHussain,我知道这会解决问题。有很多变通方法,但我正在努力最终找到一个本地解决方案。我不知道,也许我的自动调整电池出了问题。这就是为什么我决定在这里问…@StasIvanov-我以前见过类似的事情,但从未看到解决方案。我认为这要么是一个“bug”要么是“对不起,不能很好地处理多个节头”。你能展示你的其余代码吗?@aaqibhussan当然。我更新了帖子。你是不是直接访问自定义单元格对象而不是重新加载tableView来尝试的?@AaqibHussain,我知道这会解决问题。有很多变通方法,但我正在努力最终找到一个本地解决方案。我不知道,也许我的自动调整电池出了问题。这就是为什么我决定在这里问…@StasIvanov-我以前见过类似的事情,但从未看到解决方案。我认为这要么是一个“bug”,要么是“对不起,不能很好地处理多个节头”。
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: String.init(describing: PreferenceMessageSectionHeaderView.self)) as?PreferenceMessageSectionHeaderView
view?.configureWith(message: self.headerMessage)
return view
} else {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: String.init(describing: PreferenceSectionHeaderView.self)) as? PreferenceSectionHeaderView
view?.configureWith(title: section.name)
return view
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let (section, preference) = self.sectionPreferenceFor(indexPath: indexPath)
if section.type == .Single {
let cell = tableView.dequeueReusableCell(withIdentifier: String.init(describing: RadioButtonCell.self)) as! RadioButtonCell
cell.configureWith(title: preference.name, selected: preference.selected)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: String.init(describing: CheckBoxCell.self)) as! CheckBoxCell
cell.configureWith(title: preference.name, selected: preference.selected)
return cell
}
}