Swift iOS - Изменение цвета фона старой ячейки при выборе новой ячейки - PullRequest
0 голосов
/ 17 сентября 2018

Прежде чем начать, следует отметить, что если я не изменяю месяцы или даже лучше после того, как я вручную выбрал ячейку, 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
}

Вот пример, если мой вопрос неясен

Пользователь выбирает 01.01.2009, и фон этого дня теперь красный. Если пользователь перейдет на 2/2019, то tableData придется изменить, потому что осталось только 28 дней, поэтому все ячейки за этот месяц очищены. Если они вернутся к 1/2019, то tableData снова изменится, потому что теперь в месяце 31 день, поэтому цвет фона всех ячеек снова меняется на прозрачный. Однако, поскольку месяц и год 1/2019 совпадают с изначально выбранными, в cellForItem теперь я могу автоматически изменить цвет фона 1/1 на красный. Дело в том, что если я выберу 1/10, его фон изменится на красный, но 1/1 все еще останется красным . Мне нужно 1/1, чтобы изменить, чтобы очистить, когда я выбираю 1 / 10.

Ответы [ 3 ]

0 голосов
/ 17 сентября 2018

Это работает, но не является идеальным решением, потому что если ячейки не видны, код не будет работать.В моей ситуации, поскольку это календарь, ячейки всегда будут видны.Если у кого-то есть лучшее решение, я его выберу.

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
}
0 голосов
/ 17 сентября 2018

Используйте 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
}

. По отдельной проблеме вам действительно нужно сделать свою жизньпроще с датами и переосмыслите ваши объекты, если вы хотите масштабировать это.

0 голосов
/ 17 сентября 2018

Попробуйте установить состояние выбора ячейки вручную в 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
}

Таким образом, метод отмены выбора должен быть вызван и удалить цвет фона для ранее выбранной ячейки.

...