我的屏幕下方有层次结构。
-ScrollView
-ContentView
-View1
-View2
-View3
-Collectioview
-CollectioviewCell
-Tableview
-Tableviewcell
-Content
现在我的tableview内容是动态的,因此tableview单元格的高度不能是静态的。桌面视图的高度会根据单元格的数量而增加。每个细胞的高度。
基于Tableview高度,集合视图的高度应该增加,这会导致滚动视图内容视图的高度增加。
但我无法理解如何用更少的代码实现这一目标? 或者可以以编程方式完成吗?
答案 0 :(得分:4)
最通用的方法是观察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
类型。
只要您的集合视图的内容大小发生更改,并且您不需要了解视图是否已完成加载或其他任何内容,就会调用此方法。
答案 1 :(得分:1)
假设您的表格视图中的每一行都有固定的高度。
因此,表视图的高度将是tableview中的行数*行的高度。假设每行的高度为30 ,并且表视图中有 4行,那么
tableHeight = 4*30 = 120
您不必等待tableview重新加载数据。您可以使用数组的计数从表格视图中填充数据以获取行数。因此,您的行数将是您的数组的计数。 直到这里你得到了你的桌面视图的高度。现在要增加父级高度,为tableview和collectionview指定固定高度,并采用两者的高度约束出口。
在重新加载之前计算tableview的高度,并将该高度赋予tableView的高度约束。同时给予collectionView的高度约束相同的高度加上额外空间(如果有的话)。
例如:
tableViewHieghtConstraint.constant = tableHeight
collectionViewHieghtConstraint.constant = tableHeight
这会增加收藏浏览量和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:不要忘记将收集视图的底限约束到contentview。
答案 2 :(得分:1)
请完成以下步骤:
为UITableView设置行高自动:
self.tblView.rowHeight = UITableViewAutomaticDimension
同样对于集合视图,如果您还没有管理单元格的大小,可以参考:https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2
现在为ContentView创建高度约束并将其值设置为:
contentViewHieghtConstraint.constant = collectionView.contentSize.height
这将解决您的问题。
但是你当前的控件设置看起来非常笨拙,我建议你应该采用任何其他方法在单视图控制器中设置更少的控件。
答案 3 :(得分:0)
您可以覆盖UITableView
属性intrinsicContentSize
并在那里返回contentSize
。然后,当您对表格视图内容大小进行一些更改时,只需将invalidateIntrinsicContentSize()
调用到重新布局
YourCustomTableView:
override var intrinsicContentSize: CGSize { return contentSize }
YourViewController或处理布局的代码:
func refreshViewController() {
// do some stuff with your custom table view
yourCustomTableView.invalidateIntrinsicContentSize()
}
答案 4 :(得分:0)
更改您的层次结构,这不是一个好主意,但它可以正常工作
-CollectionView
-CollectioviewCell
-CollectioviewCell
-CollectioviewCell
-CollectioviewCell
-Collectioview
-CollectioviewCell
-Tableview
-Tableviewcell
-Content