滚动时集合视图单元格重复
Collection view cells duplicate when scrolling
我有一个集合视图,我有一个单元格的自定义 class。每个单元格都包含一个文本视图,这里是代码:
class CustomWriterPageCell: UICollectionViewCell, UITextViewDelegate {
fileprivate let textViewOne: UITextView = {
let tv = UITextView()
tv.backgroundColor = .cyan
tv.text = "Chapter Title"
tv.font = UIFont(name: "Avenir-Roman", size: 27)
tv.textColor = .gray
return tv
}()
}
这里是 cellForItemAt
:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WriterPageCellID", for: indexPath) as! CustomWriterPageCell
cell.backgroundColor = .clear
return cell
}
文本视图有一个我通过以下代码实现的占位符(这是在自定义单元格中 class):
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == .gray {
textView.text = nil
textView.textColor = .black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.textColor = .gray
textView.text = "Chapter Title"
}
}
问题是,无论我在第一个单元格的文本视图中键入什么,都会出现在第四个单元格中,我知道这是因为 dequeueReusableCell
而发生的,但我似乎无法解决这个问题问题。
我假设第 4 个单元格不适合当前视图(即滚动下方可用 - 即重复使用的单元格)
1) 如果您要重复使用单元格,那么您需要确保在单元格离开视图之前,您需要将 UITextView
数据保存在某处。否则它会由于重用而丢失数据(即写入的文本)。以数据 structure/any 形式保存每个单元格的数据。
2) 如果滚动到第 4 个单元格,则检查数据是否存在。如果没有,则将空状态设置为文本视图。如果你写了一些东西然后以数据 structure/any 形式保存第 4 个单元格的数据..
(你可以用这个textViewDidEndEditing()
保存当前数据)
3) 再次滚动回第一个单元格类型,那里有第一个单元格数据的保存数据 structure/any 形式的索引。
4) 现在滚动回第 4 个单元格。在重用期间,将第 4 个单元格的保存数据设置为单元格文本视图。
Data Saved at Index == Cell Index
确保正确处理用例。重用实现没有错。请确保您正确保存数据和重置数据。
问题是您没有指定在每个 CollectionViewCell 的 textView 上显示什么文本。只要您没有在 cellForItemAt indexPath
中指定相同的内容,它就会显示重复使用的单元格及其内容,如您所说,来自 dequeueReusableCell
。
对于您的特定问题的解决方案,您可以在 viewcontroller 中执行以下操作:
`var textViewContentArray = [Int: String]()` //Create a dictionary to hold the texts globally
在 textViewDidEndEditing:
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.textColor = .gray
textView.text = "Chapter Title"
} else {
guard let cell = textView.superview?.superview as? CustomWriterPageCell else {
return
}
guard let indexPath = self.collectionView.indexPath(for: cell) else { return }
textViewContentArray[indexPath.row] = textView.text
}
}
在textViewDidBeginEditing中:
func textViewDidBeginEditing(_ textView: UITextView) {
textView.textColor = .black
}
并且在cellForItemAt indexPath:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomWriterPageCell", for: indexPath) as! CustomWriterPageCell
cell.textView.delegate = self
let text = textViewContentArray[indexPath.row]
if !text.isEmpty {
cell.textView.textColor = .black
cell.textView.text = text
} else {
cell.textView.textColor = .gray
cell.textView.text = "Chapter Title"
}
return cell
}
注意:这里我假设您已将保存 collectionView 的控制器设置为 textViewInCell 的委托,如果单元格是委托,您可以使用协议更新 textViewContentArray
希望这能增加您的理解。
我建议把你要改的部分封装成模型,比如你说的textColor
、text
。不要手动更改UI显示,我的意思是通过修改模型然后刷新UI,这样就不会出现重复
这是所有表的规则,修改模型刷新UI,希望对你有用
我有一个集合视图,我有一个单元格的自定义 class。每个单元格都包含一个文本视图,这里是代码:
class CustomWriterPageCell: UICollectionViewCell, UITextViewDelegate {
fileprivate let textViewOne: UITextView = {
let tv = UITextView()
tv.backgroundColor = .cyan
tv.text = "Chapter Title"
tv.font = UIFont(name: "Avenir-Roman", size: 27)
tv.textColor = .gray
return tv
}()
}
这里是 cellForItemAt
:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WriterPageCellID", for: indexPath) as! CustomWriterPageCell
cell.backgroundColor = .clear
return cell
}
文本视图有一个我通过以下代码实现的占位符(这是在自定义单元格中 class):
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == .gray {
textView.text = nil
textView.textColor = .black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.textColor = .gray
textView.text = "Chapter Title"
}
}
问题是,无论我在第一个单元格的文本视图中键入什么,都会出现在第四个单元格中,我知道这是因为 dequeueReusableCell
而发生的,但我似乎无法解决这个问题问题。
我假设第 4 个单元格不适合当前视图(即滚动下方可用 - 即重复使用的单元格)
1) 如果您要重复使用单元格,那么您需要确保在单元格离开视图之前,您需要将 UITextView
数据保存在某处。否则它会由于重用而丢失数据(即写入的文本)。以数据 structure/any 形式保存每个单元格的数据。
2) 如果滚动到第 4 个单元格,则检查数据是否存在。如果没有,则将空状态设置为文本视图。如果你写了一些东西然后以数据 structure/any 形式保存第 4 个单元格的数据..
(你可以用这个textViewDidEndEditing()
保存当前数据)
3) 再次滚动回第一个单元格类型,那里有第一个单元格数据的保存数据 structure/any 形式的索引。
4) 现在滚动回第 4 个单元格。在重用期间,将第 4 个单元格的保存数据设置为单元格文本视图。
Data Saved at Index == Cell Index
确保正确处理用例。重用实现没有错。请确保您正确保存数据和重置数据。
问题是您没有指定在每个 CollectionViewCell 的 textView 上显示什么文本。只要您没有在 cellForItemAt indexPath
中指定相同的内容,它就会显示重复使用的单元格及其内容,如您所说,来自 dequeueReusableCell
。
对于您的特定问题的解决方案,您可以在 viewcontroller 中执行以下操作:
`var textViewContentArray = [Int: String]()` //Create a dictionary to hold the texts globally
在 textViewDidEndEditing:
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.textColor = .gray
textView.text = "Chapter Title"
} else {
guard let cell = textView.superview?.superview as? CustomWriterPageCell else {
return
}
guard let indexPath = self.collectionView.indexPath(for: cell) else { return }
textViewContentArray[indexPath.row] = textView.text
}
}
在textViewDidBeginEditing中:
func textViewDidBeginEditing(_ textView: UITextView) {
textView.textColor = .black
}
并且在cellForItemAt indexPath:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomWriterPageCell", for: indexPath) as! CustomWriterPageCell
cell.textView.delegate = self
let text = textViewContentArray[indexPath.row]
if !text.isEmpty {
cell.textView.textColor = .black
cell.textView.text = text
} else {
cell.textView.textColor = .gray
cell.textView.text = "Chapter Title"
}
return cell
}
注意:这里我假设您已将保存 collectionView 的控制器设置为 textViewInCell 的委托,如果单元格是委托,您可以使用协议更新 textViewContentArray
希望这能增加您的理解。
我建议把你要改的部分封装成模型,比如你说的textColor
、text
。不要手动更改UI显示,我的意思是通过修改模型然后刷新UI,这样就不会出现重复
这是所有表的规则,修改模型刷新UI,希望对你有用