bug 场景
我本意是用 grouped
的方式创建的 tableView
, 每组有 sectionHeader
和 sectionFooter
, 设置 tableHeaderView
, 由于 header
的高度不确定, 所以初始化 frame
为 .zero
, 在数据请求回来后更新 header
的高度.
但是 bug 就这么出现了, 第0组的 sectionHeader
的 y 值默认为 35, 也就是说 tableView
内容展示起点向下偏移 35, 可以看到 tableView
的背景色.
代码和效果图
代码
-
代码比较简单, 就是一个普通的列表, 部分写法只是为了满足本示例, 与正常开发不同, 所以还请谅解, cell 点击事件模拟数据返回后更新
header
高度.import UIKit fileprivate let UITableViewCellID = "UITableViewCellID" class ViewController: UIViewController { let size = UIScreen.main.bounds.size private lazy var header: UIView = { let v = UIView(frame: .zero) v.backgroundColor = .cyan return v }() private lazy var tableView: UITableView = { let fRect = CGRect(x: 0, y: 0, width: size.width, height: size.height) let tv = UITableView(frame: fRect, style: .grouped) tv.backgroundColor = .blue tv.separatorStyle = .none tv.rowHeight = 40 tv.showsVerticalScrollIndicator = false tv.tableHeaderView = header tv.delegate = self tv.dataSource = self tv.contentInsetAdjustmentBehavior = .never tv.register(UITableViewCell.self, forCellReuseIdentifier: UITableViewCellID) return tv }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(tableView) } } extension ViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 4 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 3 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: UITableViewCellID, for: indexPath) cell.textLabel?.text = "\(indexPath.section) 组 -- \(indexPath.row) 行" return cell } func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let header = UILabel(frame: .zero) header.backgroundColor = .red header.font = UIFont.systemFont(ofSize: 18); header.text = "\(section) 组 -- 头" return header } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 50.0 } func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { let footer = UILabel(frame: .zero) footer.backgroundColor = .green footer.font = UIFont.systemFont(ofSize: 18); footer.text = "\(section) 组 -- 尾" return footer } func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return 50.0 } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { header.frame.size.height = 200; tableView .reloadData() } }
效果图
-
效果:
-
偏移量
解决方案
经过上网查资料 和 自己的尝试, 最终解决方案就是在 header
初始化的时候设置 frame
, 起决定作用的是高度
, 设置高度
的绝对值大于 0.1 就可以, 亲测 -1 可以. 最终体现为两种方式.
方式一
-
就是一些具体的数值, 如 -1, 1, 100, 根据自己的具体需求来定.
private lazy var header: UIView = { let v = UIView(frame: CGRect(x: 0, y: 0, width: size.width, height: -1)) v.backgroundColor = .cyan return v }()
明显可以看出顶部一条线, 实际开发中可以设置为白色或透明色, 看上去没有异常为准.
方式二
-
设置高度为
CGFloat.leastNormalMagnitude
(OC 对应的变量是CGFLOAT_MIN
)private lazy var header: UIView = { let v = UIView(frame: CGRect(x: 0, y: 0, width: size.width, height: CGFloat.leastNormalMagnitude)) v.backgroundColor = .cyan return v }()
这种方案比较完美, 顶部并没有看到有线条.
更新 header 效果
-
当点击一下
cell
时更新header
高度为200
, 此时需要刷新列表, 否则展示会异常.
因为我的机型有限, 所以具体情况大家具体对待, 也可能在某些情况下不合适, 所以仅供参考.
能看到这里的, 那必须要谢谢大家支持 😄😄😄