UITableView未在UIStackView中显示

6
我有一个UIStackView,根据用户选择可以显示标签、图像、表格视图或没有任何内容。下面是动态视图的当前层次结构:
- UIStackView_Parent
- UILabel - 某些文本,固定视图 - UIStackView_Child - 这是可以显示多个东西或什么也没有的容器 - UIView - 另一个固定视图
当我使用标签或图像调用UIStackView_Child.addArrangedSubview(...)时,它完美地工作,但addArrangedSubview(tableView)不会显示表格。我将tableView.scrollEnabled设置为false,并根据单元格的数量将其框架设置为固定高度,并定义了表的cellHeight。
非常感谢您的帮助!
4个回答

11

如果不想明确设置框架高度和宽度,另一种方法是将表视图嵌入空视图中,将表视图固定在顶部、底部、左侧和右侧,并为表视图的高度设置“大于或等于”约束。


“大于等于”约束条件?这是将“空视图”的高度限制为大于或等于表格高度吗? - Pat Long - Munkii Yebee
@kliron,你能详细说明一下吗?可以提供一个截图或示例吗?我在视图和父单元格上直接设置了大于约束,但无法使其正常工作。 - Nisarg Shah

9
那是因为stackview试图尽可能压缩内容。当您最初添加tableview时,我假设它没有内容,因此stackview将其宽度压缩到0,因为它没有显示的内容。你必须做以下两件事之一:
在表格填充数据后,您必须设置tableView的frame。我通过计算每个单元格的大小来做到这一点。我知道宽度将与包含stackview的视图一样大。因此,结果会是这样的:
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)

一旦您设置了tableView的框架,stackview应该会自动调整。

13
"你必须做两件事中的其中一件",另一件是什么? - mfaani
3
另一个可能存在的限制是表格视图的高度约束。例如,tableView.heightAnchor.constraint(equalToConstant: 42).isActive = true。设置堆栈视图的高度也可以起到同样的作用。 - Leo
为什么estimatedHeight是行数而不是应该乘以行高呢? - user-123

2
您还可以使用 Combine 自动监测 UITableView 的高度:
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)

如果您没有可用的combine,则可以添加观察者:
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
    }
}

2
小心 sink 内部的强引用 self - skornos

-1
你可以使用RxSwift观察UITableView的内容大小。
    // in UIViewController

    import RxSwift

    @IBOutlet var tableViewHeightConstraint: NSLayoutConstraint!

    override public func viewDidLoad() {
        super.viewDidLoad()

        // subscribe to observe table view content size
        tableView.rx.observe(CGSize.self, "contentSize")
            .subscribe(onNext: { [weak self] newSize in
                guard let self,
                      let height = newSize?.height
                else {
                    return
                }
                // adjust table view height constraint
                self.tableViewHeightConstraint.constant = height
            })
            .disposed(by: disposeBag)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接