Search code examples
iosswiftxcodeuilocalnotificationcollectionview

Swift3 collectionView 'attempt to delete item 1 from section 1, but there are only 1 sections before the update'


My app crashed due to 'attempt to delete item 1 from section 1, but there are only 1 sections before the update'

I found other articles said that the data source must keep in sync with the collectionView or tableView, so I remove the object from my array: alarms before I delete the item in my collectionView, this works on didSelectItemAtIndexPath. But I don't know why this doesn't work.

I also tried to print the array.count, it showed the object did remove form the array.

func disableAlarmAfterReceiving(notification: UILocalNotification) {
    for alarm in alarms {
        if alarm == notification.fireDate {
            if let index = alarms.index(of: alarm) {
                let indexPath = NSIndexPath(item: index, section: 1)

                alarms.remove(at: index)
                collectionView.deleteItems(at: [indexPath as IndexPath])

                reloadCell()
            }
        }
    }
}

func reloadCell() {
    userDefaults.set(alarms, forKey: "alarms")
    DispatchQueue.main.async {
        self.collectionView.reloadData()
        print("Cell reloaded")
        print(self.alarms.count)
    }
}

Solution

  • You are having single section so you need to delete it from the 0 section. Also use Swift 3 native IndexPath directly instead of NSIndexPath.

    let indexPath = IndexPath(item: index, section: 0)
    
    alarms.remove(at: index)
    DispatchQueue.main.async {
        collectionView.deleteItems(at: [indexPath])
    }
    

    Edit: Try to break the loop after deleting items from collectionView.

    if let index = alarms.index(of: alarm) {
        let indexPath = IndexPath(item: index, section: 0)
        alarms.remove(at: index)
        DispatchQueue.main.async {
            collectionView.deleteItems(at: [indexPath])
        }
        reloadCell()
    
        break
    }