You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:33:29