![](/img/trans.png)
[英]How can I dynamically resize a tableview inside another table view's table header?
[英]How to dynamically resize table view header?
當人們點擊加載更多時,我想動態調整表格視圖標題的大小。 發生的情況是,當人們點擊加載更多時,新內容會添加到表格視圖標題中,因此高度會發生變化。 我事先不知道新的高度。
我怎樣才能做到這一點? 我現在正在做的是當人們點擊“加載更多”時,我執行下面的代碼。
@objc func expandDesc(sender: UIButton) {
loadMoreDesc = !loadMoreDesc
tableView.reloadData()
}
我可以在上面的代碼中添加什么來動態調整表視圖標題的大小?
只需使用約束,您就可以為它們設置動畫。 您不必為此重新加載整個表視圖。 您可以保持對標題的弱引用並更改其狀態,如果按下更多,則為約束設置動畫,如果是文本您想要適合,請使用 StackView 並添加/刪除 UILabel 到堆棧視圖,它應該可以完美運行。
自動布局不會自動更新表頭視圖的大小,因此我們需要“手動”進行。
我們可以使用這個擴展來幫助:
extension UITableView {
func sizeHeaderToFit() {
guard let headerView = tableHeaderView else { return }
let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
var frame = headerView.frame
// avoids infinite loop!
if height != frame.height {
frame.size.height = height
headerView.frame = frame
tableHeaderView = headerView
}
}
}
現在,當我們更新表頭視圖的內容時——這會導致它的高度改變——我們可以調用.sizeHeadrToFit()
這是一個完整的例子:
簡單的多行單元格- 青色標簽
class MultilineCell: UITableViewCell {
let label: UILabel = {
let v = UILabel()
v.numberOfLines = 0
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
label.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(label)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
// constrain label to the cell's margins guide
label.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
label.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
label.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
label.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
])
label.backgroundColor = .cyan
}
}
表標題的多行視圖- 紅色視圖中的黃色標簽
class MyTableHeaderView: UIView {
let label: UILabel = {
let v = UILabel()
v.numberOfLines = 0
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
label.translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
let g = self.layoutMarginsGuide
NSLayoutConstraint.activate([
// constrain label to the self's margins guide
label.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
label.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
label.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
])
// this avoids auto-layout complaints
let c = label.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0)
c.priority = UILayoutPriority(rawValue: 999)
c.isActive = true
backgroundColor = .red
label.backgroundColor = .yellow
}
}
示例表視圖控制器
class DynamicHeaderTableViewController: UITableViewController {
var theData: [String] = []
let myHeaderView = MyTableHeaderView()
override func viewDidLoad() {
super.viewDidLoad()
// 10 rows with 2-to-5 lines per row
for i in 1...10 {
let s = "This is row \(i)"
let n = Int.random(in: 1...4)
let a = (1...n).map { "Line \($0)" }
theData.append(s + "\n" + a.joined(separator: "\n"))
}
tableView.register(MultilineCell.self, forCellReuseIdentifier: "cell")
myHeaderView.label.text = "Select a row..."
tableView.tableHeaderView = myHeaderView
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.sizeHeaderToFit()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let c = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MultilineCell
c.label.text = theData[indexPath.row]
return c
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
myHeaderView.label.text = theData[indexPath.row]
tableView.sizeHeaderToFit()
}
}
上面的代碼將生成 10 行,每行 2 到 5 行。 在didSelectRowAt
我們將使用行中的文本更新表視圖標題。
首次啟動時的結果:
選擇“第 2 行”后:
選擇“第 3 行”后:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.