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

时间:2018-09-17 13:12:28

标签: ios swift uicollectionview uicollectionviewcell

开始之前,请注意,如果在手动选择一个单元格后仍不更改月份或更佳,didDeselectItem的确可以正常工作。

我有一个collectionView,其中的tableData为日期(1-31、1、30或1-28)。当用户选择一天时,该单元格的背景颜色变为红色。如果用户使用其他月份,则将重置tableData并再次触发cellForItem,以便将所有单元格的背景色设置为UIColor.clear。

我要跟踪最初选择的日期以及月份/年份的操作是创建3个变量,这些变量在触发didSelectItem时被初始化。当用户在cellForItem中返回该月时,我检查月和年是否匹配,如果匹配,请更改该天的背景。很好。

问题是,如果我选择其他日期,则其背景颜色确实会变为红色,但最初选择的日期仍保持红色。由于从未真正选择过某个单元格(我只是更改了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,则tableData再次更改,因为该月现在有31天,因此所有单元格的背景色都更改为再次清除。但是,由于1/2019的月份和年份与最初选择的匹配,因此我现在可以在cellForItem中自动将1/1的背景颜色再次更改为红色。问题是,如果我选择1/10,则背景的确会变为红色,但 1/1仍保持红色。选择1/10后,我需要将1/1更改为清除。

3 个答案:

答案 0 :(得分:0)

尝试在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
}

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

答案 1 :(得分:0)

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

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
}

答案 2 :(得分:0)

使用 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
}

在另一个问题上,您确实需要借助日期来使生活更轻松,并且如果要缩放比例,则需要重新考虑对象。