如何根据swift中UITableView的高度增加父视图的高度?

我有我的屏幕层次结构。

-ScrollView -ContentView -View1 -View2 -View3 -Collectioview -CollectioviewCell -Tableview -Tableviewcell -Content 

现在这里我的tableview内容是动态的,因此tableview单元格的高度不能是静态的。所以tableview的高度将根据每个单元格的单元格数和高度而增加。

基于Tableview高度,集合视图的高度应该增加,这会导致滚动视图内容视图的高度增加。

但我无法理解如何用更少的代码实现这一目标? 或者可以以编程方式完成?

在此处输入图像描述

最通用的方法是观察scroll- / table- / collectionView的contentSize属性并相应地更改大小。

要实现这一目标,您应该:

注意 :示例将用于UIScrollView,但它可以应用于任何collectionView

  • 将观察者添加到您的视图中

     scrollViewToObserveSizeOf.addObserver(observerObject, forKeyPath: "contentSize", options: [.old, .new], context: nil) 
  • 覆盖observeValue方法

     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if let scrollView = object as? UIScrollView, scrollView == scrollViewToObserveSizeOf, keyPath == "contentSize" { // Do whatever you want with size // You can get new size from scrollView.contentSize // or change?[NSKeyValueChangeKey.newKey] as? CGSize for new value // and change?[NSKeyValueChangeKey.oldKey] as? CGSize for old value // // ! Do not force unwrap this values, just never use force unwrap, // everything could happen } else { // ! Do not forget to call super.observeValue(forKeyPath:of:change:context) // if it is not object you added observer to super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } 

例如,要将它应用于UITableView,只需检查observeValue方法中的对象是否为UITableView类型。

只要更改了集合视图的内容大小,并且您不需要了解视图是否已完成加载或其他任何内容,就会调用此方法。

假设表视图中的每一行都有固定的高度。

因此,表视图的高度将是tableview *行的行数。 假设每行的高度为30 ,表格视图中有4行

 tableHeight = 4*30 = 120 

您不必等待tableview重新加载数据 。 您可以使用在tableview中填充数据的数组计数来获取行数。 因此,您的行数将是您的数组的计数。 直到这里你得到了你的桌面视图的高度。 现在要增加父高度,给tableview和collectionview指定固定高度,并选择两者的高度约束出口

只需在重新加载之前计算tableview的高度,并将该高度赋予tableView的高度约束。 同时给予collectionView的高度约束相同的高度加上额外空间(如果有)的高度。

例如: tableViewHieghtConstraint.constant = tableHeight collectionViewHieghtConstraint.constant = tableHeight

这将增加collectionview和tableView的高度,从而增加内容视图的高度。

如果要使用每个单元格的动态高度计算tableview的高度,可以使用以下方法获取高度。 虽然不建议这样做,并且在每种情况下都不起作用,但请在征得您的同意后使用。

 func reloadData() { self.tableView.reloadData() let tableHeight: CGFloat = 0 DispatchQueue.main.asyncAfter(deadline: .now()+0.3) { for i in 0...aryData.count - 1 { let frame = self.tableView.rectForRow(at: IndexPath(row: i, section: 0)) tableHeight += frame.size.height print(frame.size.height) } } tableViewHieghtConstraint.constant = tableHeight collectionViewHieghtConstraint.constant = tableHeight } 

您可以避免使用延迟或减少延迟。 如果在表视图中有大量数据要处理和显示,则此处给出延迟,然后可能需要几分之一秒。

PS:不要忘记将collectionview的底部约束赋予contentview。

请按以下步骤操作:

  1. 将行高设置为UITableView的自动:

    self.tblView.rowHeight = UITableViewAutomaticDimension

  2. 同样对于集合视图,如果您没有管理单元格的大小,可以参考: https : //medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10 -84ab5cdf35a2

  3. 现在为ContentView创建高度约束并将其值设置为:

    contentViewHieghtConstraint.constant = collectionView.contentSize.height

这将解决您的问题。

但是你当前的控件设置似乎非常笨拙,我建议你应该采用任何其他方法在单视图控制器中设置更少的控件,如果可能的话。

您可以覆盖UITableView属性intrinsicContentSize并在那里返回contentSize 。 然后,当您对表视图内容大小进行一些更改时,只需调用invalidateIntrinsicContentSize()以重新布局

YourCustomTableView: override var intrinsicContentSize: CGSize { return contentSize }

YourViewController或处理布局的代码:

func refreshViewController() { // do some stuff with your custom table view yourCustomTableView.invalidateIntrinsicContentSize() }

改变你的层次结构,这不是一个好主意,但它的工作原理

 -CollectionView -CollectioviewCell -CollectioviewCell -CollectioviewCell -CollectioviewCell -Collectioview -CollectioviewCell -Tableview -Tableviewcell -Content