无法从collectionView中删除项目

时间:2017-06-20 16:31:01

标签: ios swift uitableview uicollectionview

我有简单的collectionview,它在iphone上显示1列,在iPad上显示2列

有一个按钮可以从集合视图中删除一个项目但是当我按下按钮时出现了这个错误:

  

更新后的集合视图中包含的节数(3)必须等于更新前的集合视图中包含的节数(4),加上或减去插入或删除的节数(0)插入,0删除)。'

这是我的代码

protocol AudioListDataProtocol: class {
    func search(searchText: String)
    func playComposition(composition: Composition, data: [Composition], play: Bool)
    func endEditing()
}

class AudioListDataAdapter: NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UISearchBarDelegate, AudioItemCellProtocol {
    var delegate: AudioListDataProtocol!
    var isFavoriesList = false

    private var data = [Composition]()
    private var collectionView: UICollectionView!
    private var searchBar: UISearchBar!
    private let cellIdentifier = "AudioCellIdent"
    private var selectedIndexPath: IndexPath!
    private var cellWidth = 0 as CGFloat
    private var sectionCount = 0
    private var itemCount = 0


    //MARK: public methods
    func initSearchBar(searchBar: UISearchBar) -> Void {
        self.searchBar = searchBar
        self.searchBar.delegate = self
        self.searchBar.returnKeyType = .done
        self.searchBar.placeholder = DicionaryManager.shared.getStringValue(dKey: AMKeys.mobile_label_search_here)
    }

    func initCollection(collection: UICollectionView) -> Void {
        self.collectionView = collection
        self.collectionView.dataSource = self
        self.collectionView.delegate = self
        self.collectionView.register(UINib.init(nibName: "AudioItemCell", bundle: nil), forCellWithReuseIdentifier: cellIdentifier)
    }

    func setListData(data: [Composition], itemsPerSection: Int, itemWidth: CGFloat) -> Void {
        cellWidth = itemWidth
        self.data = data
        itemCount = itemsPerSection
        sectionCount = Int(ceil(Double(self.data.count / itemCount)))
    }

    func reload() {
        collectionView.reloadData()
    }


    //MARK: UISearchBarDelegate
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        searchBar.showsCancelButton = true
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText.characters.count >= 3 {
            if let d = delegate {
                d.search(searchText: searchText)
            }
        }
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.text = ""
        if let d = delegate {
            d.search(searchText: "")
            d.endEditing()
        }
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        if let d = delegate {
            d.endEditing()
        }
    }


    //MARK: UICollectionViewDataSource
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return sectionCount
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return itemCount
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? AudioItemCell {
            return cell
        }
        return UICollectionViewCell()
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        let c = cell as! AudioItemCell
        c.setupComposition(composition: data[curItemIndex(indexPath: indexPath)])
        c.indexPath = indexPath
        c.favoriteState = isFavoriesList
        c.delegate = self
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        PlayerManager.shared.changePlaylist()
        var item: Composition
        item = data[curItemIndex(indexPath: indexPath)] as Composition
        item.isPlaying = true
        item.showPlayer = true
        collectionView.reloadItems(at: [indexPath])
        selectedIndexPath = indexPath
        delegate.playComposition(composition: item, data: data, play: true)
    }

    func playingCompositionForReload(composition: Composition) {
        composition.isPlaying = true
        composition.showPlayer = true
        collectionView.reloadData()
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: cellWidth, height: 90)
    }


    //MARK: helpers methods
    func updateState(play: Bool) -> Void {
        if (selectedIndexPath) != nil {
            let item = data[curItemIndex(indexPath: selectedIndexPath)]
            item.isPlaying = !item.isPlaying
        } else {
            selectedIndexPath = IndexPath(row: 0, section: 0)
            let item = data[0]
            item.isPlaying = true
            item.showPlayer = true
        }

        collectionView.reloadItems(at: [selectedIndexPath])
    }   


    private func curItemIndex(indexPath: IndexPath) -> Int {
        return indexPath.section * itemCount + indexPath.item
    }


    //MARK: AudioItemCellProtocol
    func removeCellAtIndexpath(indexPath: IndexPath) {
        collectionView.performBatchUpdates({
                        self.data.remove(at: self.curItemIndex(indexPath: indexPath))
            sectionCount = Int(ceil(Double(self.data.count / self.itemCount)))
            self.collectionView.deleteItems(at: [indexPath])
        }, completion: nil)
    }
}

此按钮按下代码

delegate.removeCellAtIndexpath(indexPath: indexPath)

我在这里做错了,为什么会崩溃?

请帮助我坚持这一天。

1 个答案:

答案 0 :(得分:0)

问题在于您的numberOfItemsInSection方法和itemCount属性的使用。您将返回固定数字。您假设每个部分具有相同的固定数量的项目。相反,您应该返回给定部分的数据源中的当前记录数。

如果将数据源设置为数组数组,其中外部数组表示您的部分,每个内部数组是该部分中的项,则会有很大帮助。然后,您只需返回数组计数而不是某个预定变量。