首先,标题党一枚,UITableViewHeader 是没有办法动态调整
But,我们可以通过重新赋值 Header 来达到动态调整的效果
需求:header包含一个动态文本标签,具体内容多少可能会随业务多久修改,这里就涉及一个问题,需要多行显示,Header要随之动态变化高度。
使用Autolayout布局自定义HeaderView,一定要保证控件之间满足布局约束。
关键代码:
let label = UILabel()
label.numberOfLines = 0 // 多行
label.preferredMaxLayoutWidth = Screen.width-8*2-15*2 // 【重点】文本最大约束宽度
// 添加到 header 中和添加约束
这里最重要的是设置 UILabel 的 preferredMaxLayoutWidth, 使其在没有添加约束的时候具备计算size的能力。
当多行 Label 时,首选最大宽度。用于在 Autolayout 布局中,进行换行依据, 如果不为0,则用来计算 intrinsicContentSize
参考链接:
UILabel的preferredMaxLayoutWidth研究 – csdn
关于 preferredMaxLayoutWidth 的结论:
行数为1的 UILabel,preferredMaxLayoutWidth 不会影响。
多行时
UILabel 具备完整约束,使用 preferredMaxLayoutWidth 作为宽度换行,为0时则不会换行。
UILabel 不具备完整约束,以自身约束作为宽度换行,为0不影响。
但是这这两种情况都会在调用其父视图(或者父视图的父视图)的 [superView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] 方法计算其父视图最小宽高时,使用 preferredMaxLayoutWidth 作为换行宽度
使用Autolayout对多行文本布局,高度不准确的解决办法 – 简书
private func setupTableView(){
let header = SearchMyRaceHeaderView(frame: CGRect(x: 0, y: 0, width: Screen.width, height: 0))
tableView.tableHeaderView = header
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dWoS0aUb-1596767693677)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
更新约束
private func sizeHeaderTofit(){
let headerView = tableView.tableHeaderView! // 获取headerView
headerView.setNeedsLayout()
headerView.layoutIfNeeded() // 使布局立即生效
let smallSize = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) //获取到基于Autolayout布局控件尽可能小的大小
var tempFrame = headerView.frame
tempFrame.size.height = smallSize.height
headerView.frame = tempFrame // 直接更改frame无效
tableView.tableHeaderView = headerView // 【重点】重新为 TableView 赋值 Header
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d28amdmH-1596767693678)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sizeHeaderTofit()
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ngd1kqz3-1596767693679)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
Tips:
- 如果需要修改tableHeaderView高度,必须重新赋值,单纯修改frame布局没有效果的。
- 基于约束布局的控件可以通过, 立即生效约束和systemlayoutSizeFitting()方法获取size。从而与frame布局进行桥接转化
对于复杂的 Header 我们更喜欢使用 xib 来布局,但是通过 xib 初始化加在 Header 的 View总会出现高度和预期或者预设值不一样的问题。
后来经过反复测试发现,将创建的 xib 的 View删除,然后再自己加一个 View 进去即可正确显示高度。
动态计算UITableView中tableViewHeaderView的高度