Разрешить только выделение определенных ячеек с функцией shouldSelectItemAt indexPath - PullRequest
0 голосов
/ 24 октября 2018

Я хочу, чтобы только четыре конкретные ячейки могли быть выбраны одновременно.Когда кнопка нажата, я хочу, чтобы выбираемые ячейки были на 4 indexPath.row ниже.

Пример: в начале можно выбрать indexPath.row 44-47.Если кнопка нажата, я хочу, чтобы можно было выбрать indexPath.row 40-43 и т. Д.

Я думал о создании массива с помощью indexPath и, если кнопка нажата, числа в массивеНа 4 цифры ниже.

Чем я не знаю, как добавить это к функции shouldSelectItemAt indexPath.

Как я могу это реализовать?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Давайте рассмотрим, что элементы образуют массив строк, и вы отслеживаете выбранные индексы как диапазон.

var selectedRange: Range<Int>? {
    didSet {
        collectionView.reloadData()
    }
}

var items: [String] = [] {
    didSet {
        // To make sure that the selected indices are reset everytime this array is modified,
        // so as to make sure that nothing else breaks
        if items.count >= 4 {
            // Select the last 4 items by default
            selectedRange = (items.count - 4)..<items.count
        } else if !items.isEmpty {
            selectedRange = 0..<items.count
        } else {
            selectedRange = nil
        }
    }
}

Затем, когда вы нажимаете кнопку, чтобы уменьшить диапазон, вы можетеиспользуйте эту логику для обработки того же:

func decrementRange() {
    if var startIndex = selectedRange?.startIndex,
        var endIndex = selectedRange?.endIndex {

        startIndex = max((startIndex - 4), 0)
        endIndex = min(max((startIndex + 4), (endIndex - 4)), items.count)

        selectedRange = startIndex..<endIndex
    }
}

Затем вы можете определить, выполняется ли выбор в активном диапазоне, используя:

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {

    if let selectedRange = selectedRange {
        return selectedRange.contains(indexPath.item)
    }
    return false
}

Примечание : Я бы посоветовал вам проверить, охватывает ли это все угловые случаи, прежде чем пробовать его для производственного кода.

0 голосов
/ 24 октября 2018

Вы можете использовать IndexSet .

var allowedSelectionRow: IndexSet
allowedSelectionRow.insert(integersIn: 44...47) //Initial allowed selection rows

In collectionView(_:shouldSelectItemAt:)

return allowedSelectionRow.contains(indexPath.row) //or indexPath.item

Всякий раз, когда вам нужно:

allowedSelectionRow.remove(integersIn: 44...47) //Remove indices from 44 to 47
allowedSelectionRow.insert(integersIn: 40...43) //Add indices from 40 to 43

Преимущество от массива: как и в наборе, есть уникальность значений (без дубликатов).Содержит только целые числа, и вы можете добавить в «диапазон», что может быть полезно (добавить не все индексы, а диапазон).

После комментариев, если у вас есть только 4 строки подряд и разрешено, вы можете иметьэтот метод:

func updateAllowedSectionSet(lowerBound: Int) { 
    let newRange = lowerBound...(lowerBound+3)
    allowedSectionRow.removeAll() //Call remove(integersIn:) in case for instance that you want always the 1 row to be selectable for instance
    allowedSectionRow.insert(integersIn: newRange) 
}

Для первого вам просто нужно сделать: updateAllowedSectionSet(lowerBound: 44) вместо allowedSelectionRow.insert(integersIn: 44...47)

...