我正在使用 UICollectionViewController,我正在尝试在所选项目的循环中使用 deleteItems,如下所示:
for item in (collectionView?.indexPathsForSelectedItems)!
{
let cell = self.collectionView?.cellForItem(at: item) as! ImageCollectionCell
deleteLandGradingImage(images: ImagesData(jobNo: self.jobNo, ImageBytes: (self.array[item.item]["imageBytes"] as! String), Username: appDelegate.username)) { result in
cell.imageView.layer.borderWidth = 0
self.navigationItem.rightBarButtonItems = [self.editButton]
self.editButton.isEnabled = true
self.editButton.title = "Edit"
self.doneButton.title = "Done"
self.array.remove(at: item.item)
self.collectionView?.deselectItem(at: item, animated: true)
self.collectionView?.deleteItems(at: [item])
}
}
deleteLandGradingImage(images: ImagesData(jobNo: self.jobNo, ImageBytes: (self.array[item.item]["imageBytes"] as! String), Username: appDelegate.username)) { result in
}
是对删除单元格内图像并将其从数据库中删除的 API 的调用。
func deleteLandGradingImage(images: ImagesData, completionHandler:@escaping (_ result:Bool) -> Void) {
//Define array for returning data
var returnedResults = Bool()
//Call API
WebService().deleteLandGradingImages(images: images)
{
(result: Bool) in
DispatchQueue.main.async {
//Return our results
returnedResults = result
completionHandler(returnedResults)
}
}
}
这是WebService中的方法:
func deleteLandGradingImages(images: ImagesData, completion: @escaping (_ result: Bool) -> Void)
{
var jsonDict = [AnyHashable: Any]()
//Set Lot
jsonDict["jobNo"] = images.jobNo
//Set Image
jsonDict["imageBytes"] = images.ImageBytes
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: jsonDict, options: .prettyPrinted)
let urlComponents = NSURLComponents(string: webservice + "DeleteGradingImages");
//Assign Username
urlComponents?.user = appDelegate.username;
//Assign Password
urlComponents?.password = appDelegate.password;
//Define our URL String
let url = urlComponents?.url;
//Define URL Request
var request = URLRequest(url: url!)
//Set Header Values for request
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
//Set Header Values for request
request.setValue("application/json", forHTTPHeaderField: "Accept")
//Set Request Method to POST
request.httpMethod = "POST"
//Set Request Body to JSON Data
request.httpBody = jsonData
Alamofire.request(request)
.responseJSON { response in
if(response.error != nil)
{
completion(false)
}
else
{
let responseString = (String(data: response.data!, encoding: .utf8) != nil) as Bool
completion(responseString)
}
}
}
我的循环问题是有时它有效,有时我会得到这个错误:
Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).
有时我会收到这个错误:
Thread 1: Fatal error: Index out of range
在这条线上
self.array.remove(at: item.item)
我做错了什么?
更新
我从一个答案中得到这个:
@IBAction func deleteButtonPressed(_ sender: Any) {
let group = DispatchGroup()
let indexPaths = (collectionView?.indexPathsForSelectedItems)!
var deletes = Array<Dictionary<String, Any>>()
for item in indexPaths {
deletes.append(self.array[item.item])
}
for item in deletes {
group.enter()
deleteLandGradingImage(images: ImagesData(jobNo: self.jobNo, ImageBytes: (item["imageBytes"] as! String), Username: appDelegate.username)) { result in
let i = self.array.index { (dic) -> Bool in
return true
}
if i != nil {
self.array.remove(at: i!)
group.leave()
}
}
}
group.notify(queue: .main) {
for item in indexPaths {
let cell = self.collectionView?.cellForItem(at: item) as! ImageCollectionCell
cell.imageView.layer.borderWidth = 0
self.collectionView?.deselectItem(at: item, animated: true)
}
self.navigationItem.rightBarButtonItems = [self.editButton]
self.editButton.isEnabled = true
self.editButton.title = "Edit"
self.doneButton.title = "Done"
self.collectionView?.deleteItems(at: indexPaths)
if(self.array.count == 0)
{
self.imageCollectionDelegate?.ImageCollectionChange(false)
}
}
}
但有时我会在这一行出错:
let cell = self.collectionView?.cellForItem(at: item) as! ImageCollectionCell
这是错误:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
我注意到这只发生在 iPhone 上,如果我选择图像并滚动浏览 UICollectionView,然后单击删除按钮。
更新
我也试过这个:
@IBAction func deleteButtonPressed(_ sender: Any) {
self.createIndicator()
for item in (collectionView?.indexPathsForSelectedItems)! {
if let cell = self.collectionView?.cellForItem(at: item) as! ImageCollectionCell? {
deleteLandGradingImage(images: ImagesData(jobNo: self.jobNo, ImageBytes: (self.array[item.item]["imageBytes"] as! String), Username: appDelegate.username)) { result in
cell.imageView.layer.borderWidth = 0
self.collectionView?.performBatchUpdates({
self.array.remove(at: item.item)
self.collectionView?.deselectItem(at: item, animated: true)
self.collectionView?.deleteItems(at: [item])
}) { completed in
self.navigationItem.rightBarButtonItems = [self.editButton]
self.editButton.isEnabled = true
self.editButton.title = "Edit"
self.doneButton.title = "Done"
self.stopIndicator()
}
}
}
}
}
但是我得到这个错误:
Thread 1: Fatal error: Index out of range
在这一行:
self.array.remove(at: item.item)
最佳答案
有两个问题:
- 在使用
collectionView?.indexPathsForSelectedItems
的循环中更新 collectionView - 过于频繁地调用
collectionView?.deleteItems(at: [item])
最好的选择是对所有索引执行网络请求,然后一步将它们从 collectionView 中移除。您可以使用 DispatchGroup
将请求合并到一个链中。
一些解释:删除两个项目。 1 和 2。有时 1 会先被删除,然后 indexPathsForSelectedItems
将只包含一个索引 (1)。但是循环将尝试删除 indexPath 2 处的项目。这是一个崩溃。
在您的代码中使用 DispatchGroup 的示例:
let group = DispatchGroup()
let indexPaths = (collectionView?.indexPathsForSelectedItems)!
var deletes = [<your type>]()
for item in indexPaths {
deletes.append(array[item.item])
}
// TODO: Block UI with UIActivityIndicatorView
for item in deletes {
group.enter()
deleteLandGradingImage(images: ImagesData(jobNo: self.jobNo, ImageBytes: (item["imageBytes"] as! String), Username: appDelegate.username)) { result in
let i = self.array.index(of: item)!
self.array.remove(at: i)
group.leave()
}
}
group.notify(queue: .main) {
self.navigationItem.rightBarButtonItems = [self.editButton]
self.editButton.isEnabled = true
self.editButton.title = "Edit"
self.doneButton.title = "Done"
self.collectionView?.deleteItems(at: indexPaths)
}
关于ios - 从 UICollectionViewController 中删除单元格的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50649619/