I have below hierarchy of my screen.
-ScrollView
-ContentView
-View1
-View2
-View3
-Collectioview
-CollectioviewCell
-Tableview
-Tableviewcell
-Content
Now here my content of tableview is dynamic so height of tableview cell can't be static.So height of tableview will increase according to number of cell & height of each cell.
Based on Tableview height, Height of collection view should increase which results in increase in height of scroll view content view.
But I am not able to understand how should achieve this with less code? or can it be done programatically ?
The most universal way is to observe contentSize
property of your scroll-/table-/collectionView and to change size accordingly.
To achieve this you should:
Note: examples will be for UIScrollView, but it can be applied for any collectionView
add observer to your view
scrollViewToObserveSizeOf.addObserver(observerObject, forKeyPath: "contentSize", options: [.old, .new], context: nil)
override observeValue
method
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)
}
}
To apply it, for example, to UITableView just check if object in observeValue
method is of UITableView
type.
This method is called whenever content size of your collection view is changed and you do not need to know anything about if your view has finished loading or whatever.
Let's suppose each row in your table view has fixed height.
So height of table view would be number of row in tableview * height of row. Suppose hight of each row is 30 and there are 4 rows in table view then,
tableHeight = 4*30 = 120
You don't have to wait for tableview to reload data. You can use the count of your array from which you fill your data in tableview to get number of rows. So your number of rows would be your array's count. Till here you got the height of your tableview. Now to increase the parent height, Give fixed height to the tableview and collectionview and take a outlet of height constraint of both.
Just calculate the height of tableview before reloading and give that height to tableView's height constraint. Also give the same height plus heigh of extra space(If any) to collectionView's height constraint.
For eg :
tableViewHieghtConstraint.constant = tableHeight
collectionViewHieghtConstraint.constant = tableHeight
This will increase your collectionview's and tableView's height and thus result in increasing the height of your content view.
If you want to calculate the height of your tableview with dynamic height of each cell, following method can be used to get height. Though this is not recommended and does not work in every case so use this with your own consent.
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
}
You can avoid using delay or provide less delay. Delay is given here in case if there is large amount of data to be processed and displayed on table view then it might take some fraction of seconds.
P.S: Don't forget to give bottom constraint of collectionview to contentview.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With