Swift iOS - 选择新单元格时更改旧单元格的背景颜色



在我开始之前,应该注意的是,如果我在手动选择单元格后没有更改几个月或更好的时间,didDeselectItem确实可以正常工作。

我有一个集合视图,其中包含日期(1-31、1-30 或 1-28(的表数据。当用户选择某一天时,该单元格的背景色将变为红色。如果用户转到其他月份,则会重置表数据并再次触发 cellForItem,因此所有单元格背景颜色都设置为 UIColor.clear。

我所做的是跟踪初始选择的日期及其月份/年份,方法是创建 3 个变量,这些变量在触发时初始化didSelectItem。当用户返回到cellForItem中的该月时,我会检查月份和年份是否匹配,如果是,则更改当天的背景。它工作正常。

问题是,如果我选择不同的日期,其背景颜色确实会变为红色,但最初选择的日期也保持红色。由于从未实际选择过单元格(我只是更改了单元格中的颜色(,因此 didDeselectItem 永远不会触发以更改旧单元格的背景颜色。

如何让选择新一天时让初始日期更改其颜色?

// when a different month is shown some calculations are done to change these but those calculations aren't relevant to the question
var currentMonthIndex = Calendar.current.component(.month, from: Date())
var currentYear = Calendar.current.component(.year, from: Date())
var selectedMonth = 0
var selectedYear = 0
var selectedDay = 0
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "dayCell", for: indexPath) as! DayCell
// clears the background color of all the cells when a new month is shown 
cell.backgroundColor = UIColor..clear
if selectedMonth == currentMonthIndex && selectedYear == currentYear {
// when coming back to the selected day/month/year this makes sure the selectedDay's background is still red 
if indexPath.item == selectedDay {
cell.backgroundColor = .red
}
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? DayCell else { return }
cell.backgroundColor = .red
selectedMonth = currentMonthIndex
selectedDay = indexPath.item
selectedYear = currentYear
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? DayCell else { return }
cell.backgroundColor = UIColor.clear
}

如果我的问题不清楚,这里有一个例子

用户选择 1/1/2019,当天的背景现在为红色。如果用户转到 2/2019,则 tableData 将不得不更改,因为只有 28 天,因此该月的所有单元格都是清除的。如果他们滚动回 1/2019,表数据会再次更改,因为现在该月有 31 天,因此所有单元格背景颜色都将更改为再次清除。但是,由于 1/2019 的月份和年份与最初选择的内容匹配,因此cellForItem我现在可以再次自动将 1/1 的背景颜色更改为红色。问题是如果我选择 1/10,它的背景确实会变为红色,但 1/1 仍然保持红色。选择 1/10 后,我需要 1/1 更改为清除。

尝试在cellForItem中手动设置单元格的选择状态:

// when coming back to the selected day/month/year this makes sure the selectedDay's background is still red 
if indexPath.item == selectedDay {
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
cell.backgroundColor = .red
}

这样,应该调用取消选择方法并删除先前选择的单元格的背景色。

这有效,但不是理想的解决方案,因为如果单元格不可见,则代码将无法运行。在我的情况下,因为它是一个日历,单元格将始终可见。如果有人有更好的解决方案,我会选择它。

for cell in collectionView.visibleCells {
cell.backgroundColor = UIColor.clear
}

在将背景更改为红色之前,我在didSelectItem中使用它。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? DayCell else { return }
for cell in collectionView.visibleCells {
cell.backgroundColor = UIColor.clear
}
cell.backgroundColor = .red
selectedMonth = currentMonthIndex
selectedDay = indexPath.item
selectedYear = currentYear
}

使用willDisplay设置颜色并从cellForItemAt中删除颜色逻辑。

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? DayCell else { return }
if selectedMonth == currentMonthIndex && selectedYear == currentYear {
// when coming back to the selected day/month/year this makes sure the selectedDay's background is still red
if indexPath.item == selectedDay {
cell.backgroundColor = .red
return
}
}
cell.backgroundColor = .clear
}

在一个单独的问题上,如果你想扩展它,你真的需要用日期让你的生活更轻松,并重新考虑你的对象。

最新更新