So, I have a form to collect user data with UITextField. user can add up to 10 forms. so I thought of creating the form into a UICollectionView Cell.
my problem is within this form there is a delete button to remove the form if its not needed anymore. but this only works for the first time after that I would get an error
Fatal error: Index out of range
I am well aware of the error meaning but I have no clue how to track the row I want to delete specifically.
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)
This is how I am deleting the form. ( I am also using RxSwift and this is the easiest way I could think of to delete with arrays).
I am still fairly new to Swift development so excuse any bad coding coming from me. please guide me through this.
Update:
so I changed the function into this :
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)
and now bam getting this error:
attempt to delete item 1 from section 0 which only contains 1 items before the update
Data source implementation:
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
}
adding a new form is like this:
@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()
}
The self.data array is a global array defined to simply remove the forms cell from the ViewModel
Cell configuration:
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