You need to enable JavaScript to run this app. Swift 如何通过按钮按JSON参数值删除对应CollectionView cell?当前点删除总删首个cell
优惠活动
大模型
产品
解决方案
定价
更多

Swift 如何通过按钮按JSON参数值删除对应CollectionView cell?当前点删除总删首个cell

异常根因
  • 按钮标记缺失:cellForItemAt中未给删除按钮设置对应cell的索引值,所有按钮默认tag=0,执行删除时拿到的sender.tag恒为0,永远删除数组首位元素。
  • 取值逻辑脱钩:接口请求的pic_id从全局UserDefaults读取,未绑定当前点击cell对应的图片模型,无论点击哪个cell,发送的请求参数都是同一个固定值,与用户点击位置无关联。
  • 隐藏性能坑:cellForItemAt中给按钮添加点击事件前,未清理旧的target,cell复用时会叠加多个相同的点击事件触发,导致重复调用删除接口。
修正方案

1. 补充模型字段

在你的图片数组arrImageItems对应的模型中,新增与后端匹配的picId字段,存储每张图片对应的唯一标识:

// 示例图片模型
struct GalleryImageItem {
    var profileImage: UIImage
    var titleText: String
    var picId: String // 对应后端返回的pic_id值
}

2. 修正cell配置逻辑

在cellForItemAt方法中,为删除按钮绑定对应索引、清理重复的点击事件:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
    let item = arrImageItems[indexPath.item]
    cell.imgView.image = item.profileImage
    cell.lblTitle.text = item.titleText

    // 给删除按钮设置对应cell的索引标记
    cell.deleteButton.tag = indexPath.item
    // 清理旧的点击事件监听,避免cell复用导致的事件叠加
    cell.deleteButton.removeTarget(nil, action: nil, for: .allEvents)
    cell.deleteButton.addTarget(self, action: #selector(deleteService(sender:)), for: .touchUpInside)

    return cell
}

3. 修正删除事件的取值逻辑

修改deleteService方法,从按钮对应的索引获取模型真实的picId,接口成功后按索引精准删除cell:

@objc func deleteService(sender: UIButton) {
    let targetIndex = sender.tag
    // 越界保护,避免数组访问崩溃
    guard targetIndex < arrImageItems.count else { return }
    // 从对应位置的模型取真实的picId,不再读取全局UserDefaults缓存
    let picId = arrImageItems[targetIndex].picId
    
    print("selected picid \(picId)")
    let param = ["pic_id" : picId]
    APIReqeustManager.sharedInstance.serviceCall(param: param as [String : Any], method: .post, loaderNeed: false, loadingButton: sender as! TransitionButton, needViewHideShowAfterLoading: nil, vc: self, url: CommonUrl.edit_profile_images_remove, isTokenNeeded: true, isErrorAlertNeeded: true, isSuccessAlertNeeded: false, actionErrorOrSuccess: nil, fromLoginPageCallBack: nil) { [weak self] (resp) in
        guard let self = self else { return }
        if let resultDict = resp.dict?["result"] as? [String : Any] {
            let statusDict = resultDict["status"] as? [String : Any]
            let message = statusDict?["message"] as? String
            if message == "Success" {
                // 从数组删除对应位置的元素
                self.arrImageItems.remove(at: targetIndex)
                // 精准删除对应位置的cell,替代全量reload提升体验
                self.collectionView.deleteItems(at: [IndexPath(item: targetIndex, section: 0)])
            }
        } else {
            self.view.makeToast(CommonMessages.somethingWentWrong)
        }
    }
}

内容的提问来源于stack exchange,提问作者learn_swift

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 18:45:02