简体   繁体   English

Swift-切换CollectionView单元格以切换数组中的项目

[英]Swift - Toggling CollectionView cells to toggle items in an Array

I have two CollectionView's. 我有两个CollectionView。 One CollectionView (allHobbiesCV) is pre-populated with Hobbies you can select. 一个CollectionView(allHobbiesCV)预先填充了您可以选择的Hobbies。 The other CollectionView (myHobbiesCV) is empty, but if you tap on a hobby in the allHobbiesCV, it gets added to the myHobbiesCV. 另一个CollectionView(myHobbiesCV)为空,但是如果在allHobbiesCV中点击一个爱好,它将被添加到myHobbiesCV中。 This is all working great. 这一切都很好。

I would like the tapped allHobbiesCV cells to switch to selected, it adds the hobby to myHobbiesCV, then if the user taps the same selected cell again in the allHobbiesCV, it removes that hobby from the myHobbiesCV. 我希望将已点击的allHobbiesCV单元格切换到选中状态,它将兴趣爱好添加到myHobbiesCV中,然后,如果用户再次在allHobbiesCV中点击相同的选定单元格,它将从myHobbiesCV中删除该兴趣爱好。 Basically a toggle add/remove. 基本上是切换添加/删除。

Two things to note: 有两件事要注意:

  1. Users can manually select hobbies in myHobbiesCV, then tap a [Remove Hobby] button. 用户可以在myHobbiesCV中手动选择兴趣爱好,然后点击[Remove Hobby]按钮。
  2. Hobbies will be sorted by seasons, so there will be 4 different data sets (Winter, Spring, Summer, Autumn) for allHobbiesArray. 爱好将按季节排序,因此allHobbiesArray将有4个不同的数据集(冬季,春季,夏季,秋季)。 Depending on which season (ViewController) the user taps. 根据用户点击的季节(ViewController)。 They can select as many / few cells from each as they like. 他们可以根据需要从每个单元中选择尽可能多的单元格。

Problem: 问题:

I'm crashing on any toggle besides the first cell. 我在第一个单元格之外的任何切换上都崩溃了。 If I select the first cell in allHobbiesCV, I can select it again, and it will remove it from the myHobbiesCV. 如果选择allHobbiesCV中的第一个单元格,则可以再次选择它,它将从myHobbiesCV中删除它。 If I select that same cell again (to toggle it,) I crash. 如果我再次选择同一单元格(以进行切换),则会崩溃。 If I select any other cell besides the first, I crash. 如果我选择第一个单元格以外的其他任何单元格,则会崩溃。

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 7 from section 0 which only contains 3 items before the update'

Class Level 班级

// Winter Hobbies
let allHobbiesArray = ["Skiing", "Snowboarding", "Drinking Bourbon", "Snow Shoeing", "Snowmobiling", "Sledding", "Shoveling Snow", "Ice Skating"]
var myHobbiesArray = [String]()
var allSelected = [IndexPath]()
var didSelectIPArray = [IndexPath]()

Data Source 数据源

extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


    if collectionView == allHobbiesCV {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ALL", for: indexPath) as! AllHobbiesCell
        cell.allHobbiesLabel.text = allHobbiesArray[indexPath.item]

        if cell.isSelected {
            cell.backgroundColor = UIColor.green
        }
        else {
            cell.backgroundColor = UIColor.yellow
        }

        return cell
    }

    else {
        let cell = myHobbiesCV.dequeueReusableCell(withReuseIdentifier: "MY", for: indexPath) as! MyHobbiesCell
        cell.myHobbiesLabel.text = myHobbiesArray[indexPath.item]

        if cell.isSelected {
            cell.backgroundColor = UIColor.red
        }
        else {
            cell.backgroundColor = UIColor.yellow
        }


        return cell
    }


}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView == allHobbiesCV {
        return allHobbiesArray.count
    }
    else {
        return myHobbiesArray.count
    }

}

}

Delegate 代表

extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {


    if collectionView == allHobbiesCV {
        if myHobbiesArray.count <= 6
            self.allSelected = []

            didSelectIPArray.append(indexPath) // Store the selected indexPath in didSelectIPArray

            myHobbiesArray.insert(allHobbiesArray[indexPath.item], at: 0)
            let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
            allHobbiesCell.backgroundColor = UIColor.green

            // Store all of the selected cells in an array
            didSelectIPArray.append(indexPath) 

            myHobbiesCV.reloadData()
        }
    }


    else {
        let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
        cell.backgroundColor = UIColor.red
        allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
    }


}

// Deselecting selected cells
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {

    if collectionView == allHobbiesCV {

        // Yellow is the unselected cell color. So let's change it back to yellow.
        let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
        allHobbiesCell.backgroundColor = UIColor.yellow

        // Remove (toggle) the cells. This is where I am stuck/crashing.
        let indices = didSelectIPArray.map{ $0.item }
        myHobbiesArray = myHobbiesArray.enumerated().flatMap { indices.contains($0.0) ? nil : $0.1 }
        self.myHobbiesCV.deleteItems(at: didSelectIPArray)

        myHobbiesCV.reloadData()

        didSelectIPArray.remove(at: indexPath.item) // Remove the deselected indexPath from didSelectIPArray
    }

    else { // MyHobbies CV
        let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
        cell.backgroundColor = UIColor.yellow

        // Store the selected cells to be manually deleted.
        allSelected = self.myHobbiesCV.indexPathsForSelectedItems!

    }
}
}

Delete Button 删除按钮

@IBAction func deleteButtonPressed(_ sender: UIButton) {
    for item in didSelectIPArray {
        self.allHobbiesCV.deselectItem(at: item, animated: false) // Try deselecting the deleted items in allHobbiesCV... This is crashing.
    }
}

The issue is how I am trying to toggle the allHobbiesCV cells in didDeselect. 问题是我如何尝试切换didDeselect中的allHobbiesCV单元。 Was my approach correct in saving the selected cells in didSelectIPArray? 我的方法在将所选单元格保存在didSelectIPArray中是否正确?

I'll be happy to provide further insight if needed. 如果需要,我很乐意提供进一步的见解。 Thank you much in advance friends! 预先感谢您的朋友!

There is no need for all of that map and flatmap stuff. 不需要所有这些mapflatmap东西。 You can simply remove the object from the selected hobbies array: 您可以简单地从选定的兴趣爱好数组中删除对象:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if collectionView == allHobbiesCV {
        if myHobbiesArray.count <= 6
            self.allSelected = []
            myHobbiesArray.insert(allHobbiesArray[indexPath.item], at: 0)

            let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
            allHobbiesCell.backgroundColor = UIColor.green

            myHobbiesCV.insertItems(at: [IndexPath(item: 0, section: 0)])
        }
    } else {
        let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
        cell.backgroundColor = UIColor.red
        allSelected = self.myHobbiesCV.indexPathsForSelectedItems!
    }
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {

    if collectionView == allHobbiesCV {

        // Yellow is the unselected cell color. So let's change it back to yellow.
        let allHobbiesCell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
        allHobbiesCell.backgroundColor = UIColor.yellow

        let hobby = allHobbiesArray[indexPath.item]

        if let index = myHobbiesArray.index(of:hobby) {
             myHobbiesArray.remove(at: index)
             myHobbiesCV.deleteItems(at: [IndexPath(item: index, section:0)])
        }
    } else { // MyHobbies CV
        let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
        cell.backgroundColor = UIColor.yellow

        // Store the selected cells to be manually deleted.
        allSelected = self.myHobbiesCV.indexPathsForSelectedItems!

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM