dequeueReusableCell 导致文本改变颜色
dequeueReusableCell causes text to change color
我有一个集合视图,我正在为单元格使用自定义 class。每个单元格都有两个文本视图,chapterTitleTextView 和 chapterBodyTextView。我已将占位符添加到两个文本视图中,如下所示:
class CustomWriterPageCell: UICollectionViewCell, UITextViewDelegate {
// When the user taps on a text view
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == .gray {
textView.text = nil
textView.textColor = .black
}
}
// When the user taps out of a text view or taps on the done button in the toolbar
func textViewDidEndEditing(_ textView: UITextView) {
// If the chapter title text view is empty
if chapterTitleTextView.text.isEmpty {
chapterTitleTextView.text = "Chapter Title"
chapterTitleTextView.textColor = .gray
}
// If the chapter body text view is empty
if chapterBodyTextView.text.isEmpty {
chapterBodyTextView.text = "Chapter Body"
chapterBodyTextView.textColor = .gray
}
}
}
这是如何工作的,文本颜色最初是灰色的,并且有一些文本,当用户点击文本视图时,颜色变为黑色,文本视图中的文本被删除。
现在使用 dequeueReusableCell 有这个问题,它重用了单元格,这导致了问题编号 1:无论我在第一个单元格的文本视图中键入什么,都出现在第四个单元格中,为了解决这个问题我有创建 2 个全局列表来保存我键入的任何内容,这将显示在单元格的文本视图中,代码如下:
全局列表:
var chapterTitleText = Array(repeating: "", count: 4) // To store the chapter title text
var chapterBodyText = Array(repeating: "", count: 4) // To store the chapter body text
以下代码片段位于之前的 textViewDidEndEditing 中
// Append the chapter body text to the chapterBodyText array
let titleText = chapterTitleTextView.text
let titleRow = textView.tag //This the indexPath.row
chapterTitleText[titleRow] = titleText!
// Append the chapter title text to the chapterTitleText array
let bodyText = chapterBodyTextView.text
let bodyRow = textView.tag
chapterBodyText[bodyRow] = bodyText!
并且在 cellForItemAt:
cell.chapterBodyTextView.tag = indexPath.row
cell.chapterTitleTextView.tag = indexPath.row
cell.chapterTitleTextView.text = chapterTitleText[indexPath.row]
cell.chapterBodyTextView.text = chapterBodyText[indexPath.row]
这解决了问题 1(文本视图中的文本重复)。但是后来我遇到了一个新问题,还记得我说的占位符文本吗?当我在第一个单元格的文本视图中键入内容时,第四个单元格中文本视图的文本颜色会发生变化。我将添加一个复制问题的 GIF 以帮助读者理解:
发生这种情况是因为 UICollectionView
和 UITableView
的重用机制。由于您仅以一种方式更新颜色,因此收集 "remembers" 以前的颜色并在新单元格上重新创建其以前的状态。这里有两个基本解决方案。
首先 是为两种情况更新细胞状态,如:
if myCondition == true {
color = UIColor.gray
} else {
color = UIColor.black
}
其次是利用UICollectionViewCell
的prepareForReuse
方法
func prepareForReuse() {
// code that resets state of your cell to default
}
Apple Documentation中的方法说明
根据你的问题链,我建议你每次处理 UICollectionView
或 UITableView
时都这样做。
在您的单元格中定义一个方法 class 并将其显示自身所需的任何数据作为参数:
func configure(text : String?) { //text is optional here which means it can be nil.
//However, from my previous answer you can replace it with an empty string condition.
if let txt = text { //or if text != ""
self.chapterTitleTextView.text = txt
self.chapterTitleTextView.text.textColor = .black
}
else {// As others mentioned make sure to always handle else because cells are reusable.
self.chapterTitleTextView.text = "Chapter Title"
self.chapterTitleTextView.text.textColor = .gray
}
}
可重用单元背后的直觉是,由于它们是可重用的,您应该完全重新配置它们,而不是期望配置被保存或附加到单元。
现在,在 cellForItemAt
:
let cell = ...
cell.configure(text : chapterTitleText[indexPath.row])
请记住,通过这种方式,您无需定义全局数组。正如我之前告诉您的,这个数组只需要在您的控制器中定义,您的单元不需要知道它。您的单元格只需要知道通过 configure
函数传递的该数组的一个索引。
虽然那个全局数组可以工作,但我说的是编码的适当性。
用这种方法评论你的问题(如果有的话),我会尽量耐心回答,但不要指望(复制粘贴)代码。
我有一个集合视图,我正在为单元格使用自定义 class。每个单元格都有两个文本视图,chapterTitleTextView 和 chapterBodyTextView。我已将占位符添加到两个文本视图中,如下所示:
class CustomWriterPageCell: UICollectionViewCell, UITextViewDelegate {
// When the user taps on a text view
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == .gray {
textView.text = nil
textView.textColor = .black
}
}
// When the user taps out of a text view or taps on the done button in the toolbar
func textViewDidEndEditing(_ textView: UITextView) {
// If the chapter title text view is empty
if chapterTitleTextView.text.isEmpty {
chapterTitleTextView.text = "Chapter Title"
chapterTitleTextView.textColor = .gray
}
// If the chapter body text view is empty
if chapterBodyTextView.text.isEmpty {
chapterBodyTextView.text = "Chapter Body"
chapterBodyTextView.textColor = .gray
}
}
}
这是如何工作的,文本颜色最初是灰色的,并且有一些文本,当用户点击文本视图时,颜色变为黑色,文本视图中的文本被删除。
现在使用 dequeueReusableCell 有这个问题,它重用了单元格,这导致了问题编号 1:无论我在第一个单元格的文本视图中键入什么,都出现在第四个单元格中,为了解决这个问题我有创建 2 个全局列表来保存我键入的任何内容,这将显示在单元格的文本视图中,代码如下:
全局列表:
var chapterTitleText = Array(repeating: "", count: 4) // To store the chapter title text
var chapterBodyText = Array(repeating: "", count: 4) // To store the chapter body text
以下代码片段位于之前的 textViewDidEndEditing 中
// Append the chapter body text to the chapterBodyText array
let titleText = chapterTitleTextView.text
let titleRow = textView.tag //This the indexPath.row
chapterTitleText[titleRow] = titleText!
// Append the chapter title text to the chapterTitleText array
let bodyText = chapterBodyTextView.text
let bodyRow = textView.tag
chapterBodyText[bodyRow] = bodyText!
并且在 cellForItemAt:
cell.chapterBodyTextView.tag = indexPath.row
cell.chapterTitleTextView.tag = indexPath.row
cell.chapterTitleTextView.text = chapterTitleText[indexPath.row]
cell.chapterBodyTextView.text = chapterBodyText[indexPath.row]
这解决了问题 1(文本视图中的文本重复)。但是后来我遇到了一个新问题,还记得我说的占位符文本吗?当我在第一个单元格的文本视图中键入内容时,第四个单元格中文本视图的文本颜色会发生变化。我将添加一个复制问题的 GIF 以帮助读者理解:
发生这种情况是因为 UICollectionView
和 UITableView
的重用机制。由于您仅以一种方式更新颜色,因此收集 "remembers" 以前的颜色并在新单元格上重新创建其以前的状态。这里有两个基本解决方案。
首先 是为两种情况更新细胞状态,如:
if myCondition == true {
color = UIColor.gray
} else {
color = UIColor.black
}
其次是利用UICollectionViewCell
prepareForReuse
方法
func prepareForReuse() {
// code that resets state of your cell to default
}
Apple Documentation中的方法说明
根据你的问题链,我建议你每次处理 UICollectionView
或 UITableView
时都这样做。
在您的单元格中定义一个方法 class 并将其显示自身所需的任何数据作为参数:
func configure(text : String?) { //text is optional here which means it can be nil.
//However, from my previous answer you can replace it with an empty string condition.
if let txt = text { //or if text != ""
self.chapterTitleTextView.text = txt
self.chapterTitleTextView.text.textColor = .black
}
else {// As others mentioned make sure to always handle else because cells are reusable.
self.chapterTitleTextView.text = "Chapter Title"
self.chapterTitleTextView.text.textColor = .gray
}
}
可重用单元背后的直觉是,由于它们是可重用的,您应该完全重新配置它们,而不是期望配置被保存或附加到单元。
现在,在 cellForItemAt
:
let cell = ...
cell.configure(text : chapterTitleText[indexPath.row])
请记住,通过这种方式,您无需定义全局数组。正如我之前告诉您的,这个数组只需要在您的控制器中定义,您的单元不需要知道它。您的单元格只需要知道通过 configure
函数传递的该数组的一个索引。
虽然那个全局数组可以工作,但我说的是编码的适当性。
用这种方法评论你的问题(如果有的话),我会尽量耐心回答,但不要指望(复制粘贴)代码。