Сохраненный выбранный indexPath UICollectionView внутри UITableView - PullRequest
0 голосов
/ 09 января 2020

В настоящее время я делаю экран с UITableView со многими разделами, в которых содержится содержимое ячеек UICollectionView. Теперь я сохраняю выбранный indexPath коллекции в массив, затем сохраняю в UserDefaults (потому что требование показывает, что все ячейки были выбраны ранее при повторном открытии контроллера представления).

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

Я знаю, что это происходит, потому что я просто сохраняю только indexPath выбранного элемента без section из UITableview, который содержит представление коллекции. Но я не знаю, как проверить разделы. Может кто-нибудь, пожалуйста, помогите мне решить эту проблему? Заранее спасибо.

Я следую этому решению Как получить множественные выборы в UICollection View с помощью Swift 4

И вот что я делаю в своем коде:

var usrDefault = UserDefaults.standard
    var encodedData: Data?

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code

    if let act = usrDefault.data(forKey: "selected") {
        let outData = NSKeyedUnarchiver.unarchiveObject(with: act)
        arrSelectedIndex = outData as! [IndexPath]
    }else {
        arrSelectedData = []
    }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let optionItemCell = collectionView.dequeueReusableCell(withReuseIdentifier: "optionCell", for: indexPath) as! SDFilterCollectionCell
        let title = itemFilter[indexPath.section].value[indexPath.item].option_name

    if arrSelectedIndex.contains(indexPath) {
        optionItemCell.filterSelectionComponent?.bind(title: title!, style: .select)
        optionItemCell.backgroundColor = UIColor(hexaString: SDDSColor.color_red_50.rawValue)
        optionItemCell.layer.borderColor = UIColor(hexaString: SDDSColor.color_red_300.rawValue).cgColor
    }else {
        optionItemCell.backgroundColor = UIColor(hexaString: SDDSColor.color_white.rawValue)
        optionItemCell.layer.borderColor = UIColor(hexaString: SDDSColor.color_grey_100.rawValue).cgColor
        optionItemCell.filterSelectionComponent?.bind(title: title!, style: .unselect)
    }

    optionItemCell.layoutSubviews()

    return optionItemCell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let strData = itemFilter[indexPath.section].value[indexPath.item]
        let cell = collectionView.cellForItem(at: indexPath) as? SDFilterCollectionCell

    cell?.filterSelectionComponent?.bind(title: strData.option_name!, style: .select)
    cell?.backgroundColor = UIColor(hexaString: SDDSColor.color_red_50.rawValue)
    cell?.layer.borderColor = UIColor(hexaString: SDDSColor.color_red_300.rawValue).cgColor

    if arrSelectedIndex.contains(indexPath) {
        arrSelectedIndex = arrSelectedIndex.filter{($0 != indexPath)}
        arrSelectedData = arrSelectedData.filter{($0 != strData)}
    }else {
        arrSelectedIndex.append(indexPath)
        arrSelectedData.append(strData)

        encodedData = NSKeyedArchiver.archivedData(withRootObject: arrSelectedIndex)
        usrDefault.set(encodedData, forKey: "selected")
    }

    if let delegate = delegate {
        if itemFilter[indexPath.section].search_key.count > 0 {
            if (strData.option_id != "") {
                input.add(strData.option_id!)
                let output = input.componentsJoined(by: ",")
                data["search_key"] = itemFilter[indexPath.section].search_key.count > 0 ?  itemFilter[indexPath.section].search_key : strData.search_key;
                data["option_id"] = output
            }
        }else {
            data["search_key"] = itemFilter[indexPath.section].search_key.count > 0 ?  itemFilter[indexPath.section].search_key : strData.search_key;
            data["option_id"] = strData.option_id
        }

        delegate.filterTableCellDidSelectItem(item: data, indexPath: indexPath)
    }
}

Ответы [ 2 ]

0 голосов
/ 09 января 2020

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

Если я правильно понимаю, у вас есть представление коллекции для каждой ячейки табличного представления. Вы сохраняете выбор каждого представления коллекции, но вам также необходимо знать положение представления коллекции в родительской таблице? Для этого можно добавить свойство в свой класс UICollectionView или использовать свойство tag и установить его в соответствии с разделом, в котором он расположен в родительской таблице. Затем, когда вы сохраняете выбранное IndexPath, вы можете установить section в качестве свойства созданного вами представления коллекции (или tag в примере), чтобы каждый выбранный indexPath.section представлял табличное представление section, и indexPath.row представляет строку представления коллекции.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //...
    let collectionView = UICollectionView()
    collectionView.tag = indexPath.section
    //...
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    indexPath.section = collectionView.tag
    let strData = itemFilter[indexPath.section].value[indexPath.item]
    //...

}

По сути каждый выбранный вами путь индекса будет соответствовать следующему:

indexPath.section = таблица секция вида
indexPath.row = строка вида коллекции

IndexPath(row: 5, section: 9) будет соответствовать:
- ячейка таблицы в IndexPath(row: 0, section: 9).
---- ячейка вида коллекции в IndexPath(row: 5, section: 0)

Редактировать: так вы можете использовать сохраненные пути индекса в текущем коде

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    //...
    let tempIndexPath = IndexPath(row: indexPath.row, section: collectionView.tag)
    if arrSelectedIndex.contains(tempIndexPath) {
        //...
    } else {
        //...
    }
    //...

}

0 голосов
/ 09 января 2020

Ваше утверждение arrSelectedIndex.contains(indexPath) в методе cellForItemAt неверно.

Каждый раз, когда загружается UICollectionView в секции UITableView, он будет называться cellForItemAt для ВСЕХ ячеек.

Вот ошибка:

В В вашем примере GIF первая ячейка выбрана в первом collectionView, вы сохраните (0, 0) в массиве.

Но когда второй collectionView загрузит свои ячейки, он проверит, если indexPath (0, 0) содержится в вашем массиве. Это так, поэтому будет выбран backgroundColor.

Эта ошибка будет воспроизводиться на каждом collectionView, хранящемся в ваших разделах tableView.

Возможно, вам также следует сохранить sectionIndex вашего UITableView в вашем массиве IndexPath.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...