首页 > 解决方案 > 单击单元格内的按钮时从 UICollectionView 中删除单元格

问题描述

所以,我有一个表单来使用 UITextField 收集用户数据。用户最多可以添加 10 个表单。所以我想将表单创建为 UICollectionView 单元格。

我的问题是在此表单中,如果不再需要该表单,则有一个删除按钮可将其删除。但这仅适用于第一次之后我会收到错误

Fatal error: Index out of range

我很清楚错误的含义,但我不知道如何跟踪我要专门删除的行。

cell.deleteBtn.rx.controlEvent(.touchDown).subscribe(onNext: {_ in
           
            self.data = (self.viewModel?.form.value)!
            self.data.remove(at: row)
            self.viewModel?.form(self.data)
            self.contentViewHeightConstraints.constant -= CGFloat(779)
            

        }).disposed(by: self.disposeBag)

这就是我删除表单的方式。(我也在使用 RxSwift,这是我能想到的使用数组删除的最简单方法)。

我对 Swift 开发还很陌生,所以请原谅我的任何糟糕的编码。请指导我完成这个。

更新:

所以我把函数改成这样:

cell.deleteBtn.rx.controlEvent(.touchDown).subscribe(onNext: {_ in
           
            self.data = (self.viewModel?.form.value)!
            self.data.remove(at: row)
            self.viewModel?.form(self.data)
            self.contentViewHeightConstraints.constant -= CGFloat(779)
            // I can't use index.row so I used row
            let indexPath = IndexPath(row: row, section: 0)
            
            self.collectionView.performBatchUpdates({
                self.collectionView.deleteItems(at: [indexPath])
            }){(finished) in
                self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)
                
            }

        }).disposed(by: self.disposeBag)

现在 bam 得到这个错误:

attempt to delete item 1 from section 0 which only contains 1 items before the update

数据源实现:

self.viewModel!.form.asObservable().bind(to: self.formCV!.rx.items){
        tv,row,item in
            let cell = tv.dequeueReusableCell(withReuseIdentifier: "AddFormCell", for: IndexPath.init(row: row, section: 0)) as! AddFormCell
        
        cell.prepareForReuse()
        cell.initCellView()
        cell.iniStatesList()
        
        cell.formCountLbl.text! += " " + String(row + 1)
    
        if self.viewModel?.form.value.count ?? 0 > 1 {
            cell.deleteBtn.isHidden = false
        }else{
            cell.deleteBtn.isHidden = true
        }

添加新表单是这样的:

@IBAction func addShop(){
    var arr = viewModel?.shops.value

    if(arr?.count ?? 0 < 4) {
        arr?.append(formViewModel(shopName: "", shopAddress: "", shopState: "", shopCity: "", shopPostCode: ""))
        
        viewModel?.form.accept(arr ?? [formViewModel(shopName: "", shopAddress: "", shopState: "", shopCity: "", shopPostCode: "")])
        
        self.contentViewHeightConstraints.constant += CGFloat(779)
    }else{
        self.openError()
        
    }

self.data 数组是一个全局数组,定义为简单地从 ViewModel 中删除表单单元格

单元配置:

func configCollectionView(){
    self.collectionView.register(UINib(nibName: addFormCell.identifier, bundle: .main), forCellWithReuseIdentifier: addFormCell.identifier)

    self.shopsCV.delegate = self
    
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let size = Int((collectionView.bounds.width) / CGFloat(numberOfItemsPerRow))
    
    return CGSize(width: size, height: 779)
    
}

numberOfItemsPerRow = 1

标签: iosswiftindexinguicollectionviewdelete-row

解决方案


所以我设法通过这样做解决了这个问题:

cell.deleteBtn.rx.controlEvent(.touchDown).subscribe(onNext: {_ in
           
            
            let point = cell.deleteBtn.convert(CGPoint.zero, to: self.shopsCV)
            
            guard let indexPath = self.shopsCV.indexPathForItem(at: point)
            else{return}
            
            
            self.data = (self.viewModel?.shops.value)!
            self.data.remove(at: indexPath.row)
            self.viewModel?.shops.accept(self.data)
            
            self.shopsCV.performBatchUpdates({
            }){(finished) in
                
                self.shopsCV.reloadItems(at: self.shopsCV.indexPathsForVisibleItems)
                
            }

        }).disposed(by: cell.disposeBag)
       
            return cell

我必须在单元格中使用 disposeBag 以防止它单击删除 btn 两次或更多次。如果单元格是随机的而不是有序的,这可以正常工作。


推荐阅读