【问题标题】:Prevent scroll position from resetting when perform UITextView typing in UICollectionView在 UICollectionView 中执行 UITextView 键入时防止滚动位置重置
【发布时间】:2021-11-23 16:27:20
【问题描述】:

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

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

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

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

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

有谁知道我该怎么做

  1. 防止滚动位置自动重置?
  2. UICollectionView 将自动滚动到当前光标位置,以便用户可以看到当前输入的内容?

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

这里是代码 sn-p,关于打字时发生的事情

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 Data Source 构建的。

我试过了

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

这也解决不了问题。

【问题讨论】:

  • 您不想在这里发布代码行并希望有人去那里只是为了帮助您?
  • 对不起。因为,代码 sn-p 无法讲述整个​​故事。无论如何,我仍然发布了代码 sn-p 中最关键的部分,以及我找到的一些额外资源。
  • 这听起来是个好主意。谢谢。
  • @CheokYanCheng - 您是否有理由使用带有UICollectionViewCompositionalLayout 的集合视图而不是表格视图?
  • @DonMag 主要原因是我们对集合视图 + UICollectionViewCompositionalLayout + diffable 数据源感到舒适和熟悉。但是,我们不熟悉表格视图。我不确定表格视图是否能够生成以下i.imgur.com/ioa6izd.png(Android)和i.imgur.com/MXCApNt.png(我们在遇到这个障碍之前的中途iOS实现)

标签: ios swift uicollectionview


【解决方案1】:

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

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

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)
}

【讨论】:

  • 天哪!我记得在打字过程中使用 applySnapshot 时遇到了一些未知问题。现在未知问题消失了!谢谢你,因为这是一个救生代码sn-p。我花了一整天的时间使用 UITableView 重新实现。尽管UITableView.automaticDimension 非常方便,但在将多个图像拼贴作为标题时会产生一些奇怪的问题(在 UICollectionView 中将多个图像拼贴作为标题很好)。谢谢。我现在可以睡觉了,而不必考虑如何解决 UITableView 相关问题。
  • 旁注:系统只允许我在 21 小时后奖励赏金。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多