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
相关产品推荐
相关产品推荐

