Currently, we try to place multiple UITextView
s in UICollectionView
.
To ensure UICollectionView
's cell height, will adjust based on the dynamic content of UITextView
, this is what we have done.
- Disable scrolling in
UITextView
. - Use
.estimated(CGFloat(44))
forUICollectionViewCompositionalLayout
- Whenever there is text change, call
collectionView.collectionViewLayout.invalidateLayout()
. This is a critical step to ensure cell height will adjust accordingly.
However, calling collectionView.collectionViewLayout.invalidateLayout()
does come with a side effect.
The current scroll position of UICollectionView
will be reset, after calling collectionView.collectionViewLayout.invalidateLayout()
.
Does anyone know how can I
- Prevent unwanted auto scroll position resetting?
UICollectionView
will auto scroll to current cursor position, so that what is current being typed is visible to user?
The code to demonstrate this problem is as follow - https://github.com/yccheok/checklist-demo
Here's the code snippet, on what was happening as typing goes on
func textViewDidChange(_ checklistCell: ChecklistCell) {
//
// Critical code to ensure cell will resize based on cell content.
//
// (But comes with a side effect which will reset scroll position.)
self.collectionView.collectionViewLayout.invalidateLayout()
//
// Ensure our checklists data structure in sync with UI state.
//
guard let indexPath = collectionView.indexPath(for: checklistCell) else { return }
let item = indexPath.item
let text = checklistCell.textView.text
self.checklists[item].text = text
}
Side Note
Note, the closest solution we have came across is posted at https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01
In UITableViewController
, during text change, the author is using
DispatchQueue.main.async {
tableView?.beginUpdates()
tableView?.endUpdates()
}
It works well. But, what is the equivalent solution for UICollectionView
?
We can't try out with self.collectionView.performBatchUpdates
, as our solution is built around Diffable Data Source.
I have tried
DispatchQueue.main.async {
self.collectionView.collectionViewLayout.invalidateLayout()
}
That doesn't solve the problem either.
Thank you.