Подтвердить что ты не робот

Изменение фона ячейки UICollectionView

У меня есть UICollectionView, который я создал программно. Я бы хотел, чтобы представление коллекции выглядело следующим образом:

1. User touches cell
2. Cell background color changes
3. User releases touch
4. Cell background color changes

Это должно быть быстрое изменение цвета, которое происходит непосредственно перед тем, как селектор, связанный с действием крана, будет выполнен, в котором диспетчер представлений, содержащий представление коллекции, удаляется из стека.

Я рассматривал этот вопрос: Фон изменения ячейки UICollectionView при нажатии

в котором имеется следующая сводка методов, используемых для этой цели:

// Methods for notification of selection/deselection and highlight/unhighlight events.
// The sequence of calls leading to selection from a user touch is:
//
// (when the touch begins)
// 1. -collectionView:shouldHighlightItemAtIndexPath:
// 2. -collectionView:didHighlightItemAtIndexPath:
//
// (when the touch lifts)
// 3. -collectionView:shouldSelectItemAtIndexPath: or -    collectionView:shouldDeselectItemAtIndexPath:
// 4. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath:
// 5. -collectionView:didUnhighlightItemAtIndexPath:

Я предполагаю, что мне нужно реализовать один из вышеперечисленных методов, начиная с "когда начинается касание" и "когда касание заканчивается". Но независимо от того, что я делаю, кажется, что цвет фона меняется, а затем остается неизменным. Вот пример того, что я пытался, который не работал:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
 {
   //pop vc 
 }

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor redColor];
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

В результате цвет фона ячейки изменяется только на красный. Я также рассмотрел этот вопрос: UICollectionView Выберите и отмените выбор вопроса и попытался реализовать [UICollectionView selectItemAtIndexPath: анимированный: scrollPosition:] и вызвал его внутри didSelectItemAtIndexPath, но это не сработало или. Источник данных собрания и делегат установлены.

4b9b3361

Ответ 1

Проблема заключается в том, что вы меняете цвет на выделение и меняете его обратно на отмену выбора, а не на

Вы должны просто изменить это:

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

:

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

Кроме того, если вы не хотите ждать немного до того, как получите выделение, вы должны установить свойство delaysContentTouches для представления коллекции NO

Изменить: также убедитесь, что вы вызываете

[collectionView deselectItemAtIndexPath:indexPath animated:NO];

внутри метода -didSelectItemAtIndexPath

Ответ 2

версия Swift 3

Добавьте в класс контроллера вида следующие два метода:

// change background color when user touches cell
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.red
}

// change background color back when user releases touch
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.green
}

Обратитесь к здесь за помощью в настройке представления базовой коллекции в Swift.

Ответ 3

Изменить: ответ в Swift 3

var selectedIndex = Int ()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell

    if selectedIndex == indexPath.row
    {
        cell.backgroundColor = UIColor.green
    }
    else
    {
        cell.backgroundColor = UIColor.red
    }

    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
    selectedIndex = indexPath.row

    self.yourCollctionView.reloadData()
}

Ответ 4

Вот мое решение. И я уверен, что это действительно работает. Я предлагаю три метода выделения ячейки (selectedBackgroundView, tint cell.contentView и оттенок специальной области).

Как использовать:
1. просто наследуйте BaseCollectionViewCell и ничего не делайте,
2. Наследуем и устанавливаем specialHighlightedArea = UIView() и contentView.addSubView(specialHighlightedArea), затем планируем его или добавляем ограничение для использования автоматического макета.
3. Если вам не нужен эффект выделения, просто напишите метод с именем "shouldHighlightItemAtIndexPath", определенный UICollectionViewDelegate и сделайте его возвратом false или установите cell.shouldTintBackgroundWhenSelected = false и установите specialHighlightedArea = nil и удалите его из супервизора.

/// same with UITableViewCell selected backgroundColor
private let highlightedColor = UIColor(rgb: 0xD8D8D8) 

/// you can make all your collectionViewCell inherit BaseCollectionViewCell
class BaseCollectionViewCell: UICollectionViewCell {

    /// change it as you wish when or after initializing
    var shouldTintBackgroundWhenSelected = true

    /// you can give a special view when selected
    var specialHighlightedArea: UIView? 

    // make lightgray background display immediately(使灰背景立即出现)
    override var isHighlighted: Bool { 
        willSet {
            onSelected(newValue)
        }
    }

    // keep lightGray background until unselected (保留灰背景)
    override var isSelected: Bool { 
        willSet {
            onSelected(newValue)
        }
    }

    func onSelected(_ newValue: Bool) {
        guard selectedBackgroundView == nil else { return }
        if shouldTintBackgroundWhenSelected {
            contentView.backgroundColor = newValue ? highlightedColor : UIColor.clear
        }
        if let area = specialHighlightedArea {
            area.backgroundColor = newValue ? UIColor.black.withAlphaComponent(0.4) : UIColor.clear
        }
    }
}

extension UIColor {
    convenience init(rgb: Int, alpha: CGFloat = 1.0) {
        self.init(red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgb & 0xFF00) >> 8) / 255.0, blue: CGFloat(rgb & 0xFF) / 255.0, alpha: alpha)
    }
}