简体   繁体   中英

UITableView not shown inside UIStackView

I have a UIStackView where it can show a label, image, table view or nothing based on user selection. Here is my current hierarchy for the dynamic view:

  • UIStackView_Parent
    • UILabel - some text, fixed view
    • UIStackView_Child - this is the container that can show multiple things or nothing
    • UIView - another fixed view

When I call UIStackView_Child.addArrangedSubview(...) with a label or image it works perfectly, but addArrangedSubview(tableView) does not show the table. I have tableView.scrollEnabled = false and set frame to fixed height based on number of cell and defined the table's cellHeight .

Any help would be much appreciated, thanks!

在没有明确设置框架高度和宽度的情况下执行此操作的另一种方法是将表视图嵌入到空视图中,将表视图固定到顶部,底部,左侧和右侧,并将“大于或等于”约束设置为表格视图的高度。

That's because stackview tries to compress content as much as possible. When you initally add a tableview, I'm assuming it has no content, so stackview compresses the width to 0 because it has nothing to show. You have to do one of two things:

After the table gets populated with data, you have to set the tableView's frame. I do this by calculating how big each cell is going to be. I know the width is going to be as big as the view that contains stackview. So it winds up being something like

let estimatedHeight = tableView.numberOfRows(inSection: 0) //You may need to modify as necessary
let width = parentView.frame.size.width
tableView.frame = CGRect(x: 0, y: 0, width: width, height: estimatedHeight)

Once you set the tableView's frame, stackview should automatically adjust.

You can also automatically monitor the height of the UITableView with Combine:

import Combine

var tableViewHeightConstraint: NSLayoutConstraint?
var cancellables: Set<AnyCancellable> = []

// Table View Content Size monitor
tableView.publisher(for: \.contentSize)
    .receive(on: DispatchQueue.main)
    .sink { self.tableViewHeightConstraint?.constant = $0.height }
    .store(in: &cancellables)

Or if you don't have combine available you can add an Observer:

tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if(keyPath == "contentSize") {
        // Here you could get from change or simple get it directly from the table view
        tableViewHeightConstraint?.constant = tableView.contentSize.height
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM