Swift4 - 动态计算UITableView中tableHeaderView的高度 - 获取子控件高度和宽度

时间:2022-04-25 20:31:20

1.固定高度的 tv头部,不根据数据源隐藏某些控件,适用下面的方法

    override init(frame: CGRect) {
super.init(frame: frame)
self.translatesAutoresizingMaskIntoConstraints = false
} override func didMoveToSuperview() {
super.didMoveToSuperview()
if let superV = self.superview{
self.leadingAnchor.constraint(equalTo: superV.leadingAnchor).isActive = true
self.topAnchor.constraint(equalTo: superV.topAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: superV.trailingAnchor).isActive = true
}
}

  使用的时候很简单

    /// tv的 头部
private lazy var tvHeaderView = JYSilverCoinTopView() tv.tableView.tableHeaderView = tvHeaderView
tvHeaderView.delegate = self
tv.translatesAutoresizingMaskIntoConstraints = false

  

2.下面的方法:适用 更具数据源 动态改变 头部高度

核心 :

    /// 重置 tableview的header的frame
private func sizeHeaderToFitForTableHeaderView() {
//FIXME: 这里一定要用过滤,不然会得到默认自带的headerView,高度还不可控
if let headerView = tableView.tableHeaderView {
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
var frame = headerView.frame
frame.size.height = height
frame.size.width = self.frame.size.width
headerView.frame = frame
DDLOG(message: frame)
tableView.tableHeaderView = headerView
}
}
    /// 获取 子控件高度
func sizeHeaderToFit(view:UIView) {
view.setNeedsLayout()
view.layoutIfNeeded()
let width = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).width
let height = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
}

  

可以参考 :
https://blog.csdn.net/longshihua/article/details/78595502

1. headerView 设置

import UIKit

class JYNewCardDetailHeaderV: UIView {

    /// 储值卡总耗卡
let dyczkzhkLabel = UILabel(text: "储值卡总耗卡", fontSize: 16, isSetBoldFontSize: true, textColor: UIColor.init(hexColor: "424242"), textAlignment: .left) override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
} required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
} func configData(){ }
}
extension JYNewCardDetailHeaderV{ func setupUI() { //VFL或者 layout设置 要把这个设置为false , snapkit 正常设置,不写的话界面也正常,就是报约束错误
self.translatesAutoresizingMaskIntoConstraints = false let vd : [String:UIView] = ["dyczkzhkLabel":dyczkzhkLabel
vd.fastAddToView(self)
self.fastAddConstraints("|[dyczkzhkLabel]|", vd)
self.fastAddConstraints("V:|-10-[dyczkzhkLabel]-10-|", vd)
}
}

  

2. 使用这个view的地方配置

import Foundation

private let cellID = "JYNewCardDetailCell"
class JYStatmentCarView: UIView { 1. //创建headerV
let headerV = JYNewCardDetailHeaderV(frame: CGRect.zero) //创建tableview
fileprivate lazy var tableView : UITableView = {
let tableView = UITableView.init(frame: CGRect.zero, style: .plain)
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.register(JYNewCardDetailCell.self, forCellReuseIdentifier: cellID)
return tableView
}() override init(frame: CGRect) {
super.init(frame: frame)
self.translatesAutoresizingMaskIntoConstraints = false
self.configUI()
} //3.重新计算header的frame
override func layoutSubviews() {
super.layoutSubviews()
sizeHeaderToFit()
}
/// 重置 tableview的header的frame
func sizeHeaderToFit() {
let headerView = tableView.tableHeaderView headerView?.setNeedsLayout()
// 立马布局子视图
headerView?.layoutIfNeeded() let height = headerView?.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height ?? 0
var frame = headerView?.frame ?? CGRect.zero
frame.size.height = height
headerView?.frame = frame
// 重新设置tableHeaderView
tableView.tableHeaderView = headerView
} required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
} /// 布局UI
private func configUI() {
DDLOG(message: "创建卡相关") let vd : [String:UIView] = ["tableView":tableView]
let metrics: [String: Any] = [ "DeviceWidth": JY_DEVICE_WIDTH]
vd.fastAddToView(self)
self.fastAddConstraints("|[tableView(DeviceWidth)]|", vd, [], metrics)
self.fastAddConstraints("V:|[tableView]|", vd, [], metrics) //2.设置tableview的headerView, 并且一定设置headerV的约束
tableView.tableHeaderView = headerV
    
    //VFL设置
headerV.topAnchor.constraint(equalTo: headerV.superview?.topAnchor ?? tableView.topAnchor).fastActive()
headerV.leftAnchor.constraint(equalTo: self.leftAnchor).fastActive()
headerV.rightAnchor.constraint(equalTo: self.rightAnchor).fastActive()     //snapkit 设置
// headerV.snp.makeConstraints { (make) in
// make.top.equalToSuperview()
// make.left.right.equalTo(self)
// }
}
}