Swift4

来源:互联网 发布:无人机模拟器软件 编辑:程序博客网 时间:2024/05/16 01:16

开发的过程中,经常使用UITableView的tableHeaderView视图,对于固定高度的tableHeaderView,我们使用非常简单。创建一个自定义视图,计算好固定高度即可。如果要动态更新tableHeaderView的高度,仅仅是将自定义的view进行计算高度,有时候我们会发现tableHeaderView高度还是原来的高度,没有发生变化,在是显示的内容变多之后,会有部分内容看不到。那么一起来看看如何处理?


实现功能:

1)自定义一个UIView,包含两个UILabel,使用SnapKit进行布局

2)  默认动态计算内容高度,点击导航栏上的segmentControl进行增加和减少内容,进一步更新tableHeaderView的高度。


实现代码:

自定义视图部分

import UIKitimport SnapKitclass CustomHeaderView: UIView {    lazy var content: UILabel = {        let label = UILabel()        label.numberOfLines = 0        return label    }()    lazy var info: UILabel = {        let label = UILabel()        label.numberOfLines = 0        return label    }()        override init(frame: CGRect) {        super.init(frame: frame)        setupUI()    }        required init?(coder aDecoder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }        func setupUI() {        backgroundColor = UIColor.gray        addSubview(content)        addSubview(info)        addConstraints()    }        func addConstraints() {        content.snp.makeConstraints { (make) in            make.left.right.top.equalToSuperview().inset(10)        }        info.snp.makeConstraints { (make) in            make.left.right.equalTo(content)            make.top.equalTo(content.snp.bottom).offset(10)            make.bottom.equalToSuperview().offset(-10)        }    }}
上面代码非常简单,添加了两个label,并添加约束,注意第二个label,bottom的约束要进行设置,相对于父视图的位置,不然得不到正确的高度。


接下来看ViewController部分

class ViewController: UIViewController {    lazy var customView = CustomHeaderView()    lazy var tableView: UITableView = {        let table = UITableView()        table.dataSource = self        table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")        return table    }()    @IBOutlet var segment: UISegmentedControl?        override func viewDidLoad() {        super.viewDidLoad()        addSubViews()        setCustomViewContent()        segment?.addTarget(self, action: #selector(tapSegemntControl(_:)), for: .valueChanged)    }        func addSubViews() {        view.addSubview(tableView)        tableView.snp.makeConstraints { (make) in            make.left.right.top.bottom.equalToSuperview()        }        tableView.tableHeaderView = customView        customView.snp.makeConstraints { (make) in            make.top.equalToSuperview()            make.left.right.equalTo(view) // 确定的宽度,高度由子视图决定        }    }        func setCustomViewContent() {        customView.content.text = "患难及困苦,是磨炼人格的最高学府;——苏格拉底。不认识痛苦,就不是一条好汉。——雨果;永远不要因承认错误而感到羞耻,因为承认错误也可以解释作你今天更聪敏。——马罗;"        customView.info.text = "自古奇人伟士,不屈折于忧患,则不足以其学。——方孝孺;世上最可贵的是时间,世上最奢靡的是挥霍时光。——莫扎特;我要扼住命运的咽喉,它决不能使我完全屈服。——贝多芬;无论是美女的歌声,还是鬣狗的狂吠,无论是鳄鱼的眼泪,还是恶狼的嚎叫,都不会使我动摇。——恰普曼;成功=艰苦的劳动+正确的方法+少说空话。——爱因斯坦;"    }        override func viewDidLayoutSubviews() {        super.viewDidLayoutSubviews()        sizeHeaderToFit()    }        func sizeHeaderToFit() {        let headerView = tableView.tableHeaderView!                headerView.setNeedsLayout()        // 立马布局子视图        headerView.layoutIfNeeded()            let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height        var frame = headerView.frame        frame.size.height = height        headerView.frame = frame                // 重新设置tableHeaderView        tableView.tableHeaderView = headerView    }        @objc func tapSegemntControl(_ segment: UISegmentedControl) {        if segment.selectedSegmentIndex == 0 {            customView.content.text = "永远不要因承认错误而感到羞耻,因为承认错误也可以解释作你今天更聪敏。——马罗;"            customView.info.text = "书籍并不是没有生命的东西,它包藏着一种生命的潜力,与作者同样地活跃。不仅如此,它还像一个宝瓶,把作者生机勃勃的智慧中最纯净的精华保存起来。——弥尔顿"        } else {            customView.content.text = " ——佚名永远不要因承认错误而感到羞耻,因为承认错误也可以解释作你今天更聪敏。——马罗;自己打败自己是最可悲的失败,自己战胜自己是最可贵的胜利。 ——佚名永远不要因承认错误而感到羞耻,因为承认错误也可以解释作你今天更聪敏。——马罗;自己打败自己是最可悲的失败,自己战胜自己是最可贵的胜利。 ——佚名"            customView.info.text = "书籍并不是没有生命的东西,它包藏着一种生命的潜力,与作者同样地活跃。不仅如此,它还像一个宝瓶,把作者生机勃勃的智慧中最纯净的精华保存起来。——弥尔顿书籍并不是没有生命的东西,它包藏着一种生命的潜力,与作者同样地活跃。不仅如此,它还像一个宝瓶,把作者生机勃勃的智慧中最纯净的精华保存起来。——弥尔顿书籍并不是没有生命的东西,它包藏着一种生命的潜力,与作者同样地活跃。不仅如此,它还像一个宝瓶,把作者生机勃勃的智慧中最纯净的精华保存起来。——弥尔顿"        }        //tableView.beginUpdates()        sizeHeaderToFit()        //tableView.endUpdates()    }}

代码实现分析:


1)添加了tableView并设置了约束,然后把自定义视图(customView)设置为tableHeaderView,并设置约束,对于customView我们需要设置确定的宽度,代码中是相对于view进行添加约束,而且没有设置bottom,由子视图实现父视图的高度

2)setCustomViewContent函数是为customView中的子视图设置初始化内容

3)主要是在sizeHeaderToFit()函数,这里面会对customView进行自动布局计算其高度,并且重新赋值给tableHeaderView实现动态更新

4)tapSegemntControl函数实现内容替换,更新高度,可以看到注释了tableView.beginUpdates()和tableView.beginUpdates(),这两个方法可以根据高度的变化以动画的方式进行移动


最后添加extension,实现协议

extension ViewController: UITableViewDataSource {    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return 15    }    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)        cell.textLabel?.text = "第\(indexPath.row)"        return cell    }}


实现效果:





参考:

How to size a table header view using Auto Layout in Interface Builder




原创粉丝点击