繁体   English   中英

在 UICollectionView 中执行 UITextView 输入时防止滚动 position 重置

[英]Prevent scroll position from resetting when perform UITextView typing in UICollectionView

目前,我们尝试在UICollectionView中放置多个UITextView

为了确保UICollectionView的单元格高度,将根据UITextView的动态内容进行调整,这就是我们所做的。

  • UITextView中禁用滚动。
  • .estimated(CGFloat(44))用于UICollectionViewCompositionalLayout
  • 每当有文本更改时,调用collectionView.collectionViewLayout.invalidateLayout() 这是确保单元格高度相应调整的关键步骤。

但是,调用collectionView.collectionViewLayout.invalidateLayout()确实会带来副作用。

在调用collectionView.collectionViewLayout.invalidateLayout()之后,当前滚动 UICollectionView 的UICollectionView将被重置。

在此处输入图像描述

有谁知道我怎么能

  1. 防止滚动 position 自动重置?
  2. UICollectionView将自动滚动到当前 cursor position,以便用户可以看到当前正在键入的内容?

演示此问题的代码如下 - https://github.com/yccheok/checklist-demo

这是代码片段,关于打字过程中发生的事情

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
}

边注

请注意,我们遇到的最接近的解决方案发布在https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01

UITableViewController中,在文本更改期间,作者正在使用

DispatchQueue.main.async {
    tableView?.beginUpdates()
    tableView?.endUpdates()
}

它运作良好。 但是, UICollectionView的等效解决方案是什么?

我们不能尝试使用self.collectionView.performBatchUpdates ,因为我们的解决方案是围绕 Diffable 数据源构建的。

我努力了

DispatchQueue.main.async {
    self.collectionView.collectionViewLayout.invalidateLayout()
}

那也解决不了问题。

除非您正在利用UICollectionViewCompositionalLayout的其他布局功能,否则我认为使用表格视图会是更好的途径。

但是,如果您对 textViewDidChange textViewDidChange(...) function 进行这两项更改,您可能会得到想要的结果:

func textViewDidChange(_ checklistCell: ChecklistCell) {
    //
    // Critical code to ensure cell will resize based on cell content.
    //
    
    // 1. DO NOT call this here...
    //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
    
    // 2. update your diffable data source here
    applySnapshot(true)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM