【问题标题】:How to increase the height of parent view according to height of UITableView in swift?如何在swift中根据UITableView的高度增加父视图的高度?
【发布时间】:2018-02-16 11:36:27
【问题描述】:

我的屏幕有以下层次结构。

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

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

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

但我无法理解如何用更少的代码来实现这一点? 还是可以通过编程方式完成?

【问题讨论】:

  • 这会帮助你printfriendly.com/…
  • 通过代表......也许......但整个概念似乎很奇怪。
  • 我也是。你能告诉我最好的解决方法吗

标签: ios swift uitableview


【解决方案1】:

最通用的方法是观察你的 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 类型。

每当您的集合视图的内容大小发生变化并且您不需要知道您的视图是否已完成加载或其他任何事情时,都会调用此方法。

【讨论】:

    【解决方案2】:

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

    所以表格视图的高度将是表格视图中的行数 * 行的高度。假设每行的高度为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
        }  
    

    您可以避免使用延迟或提供更少的延迟。如果有大量数据要处理并显示在表格视图上,则此处给出延迟,则可能需要几分之一秒。

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

    【讨论】:

    • 我不知道 tableview 何时完成加载,因为没有回调,然后获取它的高度和集合视图的设置高度。请问我应该在哪个代码块设置集合视图的高度。
    • @Techiee 还添加了动态高度计算的解决方法。请参考我的回答。
    【解决方案3】:

    请执行以下步骤:

    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

    这将解决您的问题。

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

    【讨论】:

      【解决方案4】:

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

      您的自定义表格视图: override var intrinsicContentSize: CGSize { return contentSize }

      YourViewController 或处理布局的代码:

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

      【讨论】:

        【解决方案5】:

        改变你的层次结构,这不是一个好主意,但它有效

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多