如何实现Notification避免侧滑删除后已删项重新出现?
问题解决思路与代码修正
你的核心问题是数据源没有全局共享,导致删除操作只在当前控制器的局部数组生效,其他控制器的数组还是旧数据,加上可能存在的控制器生命周期中重新加载旧数据的逻辑,才会出现已删除项重现的情况。以下是具体修正方案:
第一步:用单例统一管理数据源
先创建一个全局的数据源管理类,确保所有控制器使用的是同一个memes数组实例:
class MemeManager { // 单例实例,全局唯一 static let shared = MemeManager() // 共享的memes数组 var memes: [Meme] = [] // 私有初始化,保证只能通过shared获取实例 private init() {} }
之后所有控制器都通过MemeManager.shared.memes访问数据,替换原来的局部memes数组。
第二步:修正Notification实现
1. 定义规范的通知名称
用扩展统一管理通知名,避免字符串拼写错误:
extension Notification.Name { static let memeDeleted = Notification.Name("memeDeleted") }
2. 修改TableView的删除逻辑
删除单例中的数据,再发送通知:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { // 删除单例中的数据 MemeManager.shared.memes.remove(at: indexPath.row) // 删除当前行(无需额外reloadData,deleteRows已更新界面) tableView.deleteRows(at: [indexPath], with: .left) // 发送通知告知其他控制器数据更新 NotificationCenter.default.post(name: .memeDeleted, object: nil) } }
3. 修正CollectionView的观察者逻辑
确保CollectionView使用单例数据源,并正确响应通知:
override func viewDidLoad() { super.viewDidLoad() let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: 118, height: 118) collectionView.collectionViewLayout = layout // 添加观察者 NotificationCenter.default.addObserver(self, selector: #selector(didDeleteMeme), name: .memeDeleted, object: nil) } @objc func didDeleteMeme() { // 重新加载CollectionView,此时用的是单例的最新数据 collectionView.reloadData() } // 数据源方法替换为单例数组 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return MemeManager.shared.memes.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MemeCollectionCell", for: indexPath) as! MemeCollectionCell let meme = MemeManager.shared.memes[indexPath.item] // 配置cell内容... return cell } // 记得在控制器销毁时移除观察者,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) }
第三步:检查控制器生命周期逻辑
如果你的TableView/CollectionView控制器在viewWillAppear等方法中存在重新从本地存储(比如UserDefaults、CoreData)加载旧数据的逻辑,会覆盖单例中的最新数据,导致已删除项重现。需要修改这部分逻辑:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 不要重新加载旧数据,直接刷新界面即可(确保显示单例的最新数据) tableView.reloadData() }
内容的提问来源于stack exchange,提问作者mairo
相关产品推荐
相关产品推荐

