为 UITableView 启用分页后 table 重新加载后 UITableViewCell 的奇怪行为
Weird behaviour of UITableViewCell after table reload when paging enabled for UITableView
我有一个 UITableView
并且在 UITableViewCell
内,我添加了视图并尝试根据屏幕高度或 UITableView
设置该视图的高度或单元格的高度s height
。最初,我能够做到这一点,但是在 viewWillAppear
重新加载 table 时,无法为该视图或单元格的高度设置正确的高度。是身高问题还是其他什么问题,无法识别。任何帮助将不胜感激,感谢您的回复。问题的标题可能会令人困惑,或者您是否发现了任何不相关的代码,欢迎提出建议(编辑)。
代码:
import UIKit
class PageViewController: UIViewController {
@IBOutlet weak var tblPager: UITableView!
let screenHeight = UIScreen.main.bounds.size.height
let vColors: [UIColor] = [.red, .blue, .orange, .brown, .cyan, .darkGray, .green, .red, .blue, .orange, .brown, .cyan, .darkGray, .green]
var pageSizeHeight: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
pageSizeHeight = screenHeight - (getTopSafeArea() + getBottomSafeArea() + 54)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
delay(interval: 10.0) {
print("Reload table after 10 seconds")
self.tblPager.reloadData()
}
}
}
//MARK:- TableView Delegate
extension PageViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vColors.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PageCell", for: indexPath) as! PageCell
cell.backgroundColor = vColors[indexPath.row]
cell.viewHeight.constant = pageSizeHeight
return cell
}
}
class PageCell: UITableViewCell {
@IBOutlet weak var vwPage: UIView!
@IBOutlet weak var viewHeight: NSLayoutConstraint!
}
func getTopSafeArea() -> CGFloat {
let window = UIApplication.shared.keyWindow
let topPadding = window?.safeAreaInsets.top ?? 0
return topPadding
}
func getBottomSafeArea() -> CGFloat {
let window = UIApplication.shared.keyWindow
let bottomPadding = window?.safeAreaInsets.bottom ?? 0
return bottomPadding
}
func delay(interval: TimeInterval, closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
closure()
}
}
输出:
如果所有单元格都具有相同的高度,为什么不在 viewWillLayoutSubviews
方法中设置 rowHeight
属性?
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tblPager.rowHeight = tblPager.frame.height
}
感谢@Desdenova 纠正我
通过在 PageViewController
的 viewDidLoad
中将 tblPager
的 dataSource
和 delegate
设置为自身并设置 rowHeight
属性 在 viewDidLayoutSubviews
中,tableView 的行为符合预期。
override func viewDidLoad() {
super.viewDidLoad()
tblPager.register(UINib(nibName: "PageTableViewCell", bundle: nil), forCellReuseIdentifier: "PageCell")
tblPager.dataSource = self
tblPager.delegate = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tblPager.rowHeight = tblPager.frame.size.height
}
Link 到 tableView 的高度,你的 table view 有你需要的所有尺寸。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
// ...
cell.viewHeight.constant = tableView.frame.size.heigh
// ...
}
或删除viewHeight
约束并使用委托方法设置行高
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}
UPD:
TableView 使用 estimatedRowHeight
计算其滚动偏移量。如果我们启用了分页但未配置 estimatedRowHeight
.
,这确实会在重新加载期间产生问题
解决方案一:
实施 estimatedHeightForRowAt
委托
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}
方案二:
设置 tableView.estimatedRowHeight = 0
并使用 heightForRowAt
委托而不是 viewHeight
约束
我有一个 UITableView
并且在 UITableViewCell
内,我添加了视图并尝试根据屏幕高度或 UITableView
设置该视图的高度或单元格的高度s height
。最初,我能够做到这一点,但是在 viewWillAppear
重新加载 table 时,无法为该视图或单元格的高度设置正确的高度。是身高问题还是其他什么问题,无法识别。任何帮助将不胜感激,感谢您的回复。问题的标题可能会令人困惑,或者您是否发现了任何不相关的代码,欢迎提出建议(编辑)。
代码:
import UIKit
class PageViewController: UIViewController {
@IBOutlet weak var tblPager: UITableView!
let screenHeight = UIScreen.main.bounds.size.height
let vColors: [UIColor] = [.red, .blue, .orange, .brown, .cyan, .darkGray, .green, .red, .blue, .orange, .brown, .cyan, .darkGray, .green]
var pageSizeHeight: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
pageSizeHeight = screenHeight - (getTopSafeArea() + getBottomSafeArea() + 54)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
delay(interval: 10.0) {
print("Reload table after 10 seconds")
self.tblPager.reloadData()
}
}
}
//MARK:- TableView Delegate
extension PageViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vColors.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PageCell", for: indexPath) as! PageCell
cell.backgroundColor = vColors[indexPath.row]
cell.viewHeight.constant = pageSizeHeight
return cell
}
}
class PageCell: UITableViewCell {
@IBOutlet weak var vwPage: UIView!
@IBOutlet weak var viewHeight: NSLayoutConstraint!
}
func getTopSafeArea() -> CGFloat {
let window = UIApplication.shared.keyWindow
let topPadding = window?.safeAreaInsets.top ?? 0
return topPadding
}
func getBottomSafeArea() -> CGFloat {
let window = UIApplication.shared.keyWindow
let bottomPadding = window?.safeAreaInsets.bottom ?? 0
return bottomPadding
}
func delay(interval: TimeInterval, closure: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
closure()
}
}
输出:
如果所有单元格都具有相同的高度,为什么不在 viewWillLayoutSubviews
方法中设置 rowHeight
属性?
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tblPager.rowHeight = tblPager.frame.height
}
感谢@Desdenova 纠正我
通过在 PageViewController
的 viewDidLoad
中将 tblPager
的 dataSource
和 delegate
设置为自身并设置 rowHeight
属性 在 viewDidLayoutSubviews
中,tableView 的行为符合预期。
override func viewDidLoad() {
super.viewDidLoad()
tblPager.register(UINib(nibName: "PageTableViewCell", bundle: nil), forCellReuseIdentifier: "PageCell")
tblPager.dataSource = self
tblPager.delegate = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tblPager.rowHeight = tblPager.frame.size.height
}
Link 到 tableView 的高度,你的 table view 有你需要的所有尺寸。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
// ...
cell.viewHeight.constant = tableView.frame.size.heigh
// ...
}
或删除viewHeight
约束并使用委托方法设置行高
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}
UPD:
TableView 使用 estimatedRowHeight
计算其滚动偏移量。如果我们启用了分页但未配置 estimatedRowHeight
.
解决方案一:
实施 estimatedHeightForRowAt
委托
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.size.height
}
方案二:
设置 tableView.estimatedRowHeight = 0
并使用 heightForRowAt
委托而不是 viewHeight
约束