我的应用使用flickr Api搜索照片并通过collectionView呈现。
我也想添加我喜欢的照片。
因此,我在单元格上添加了按钮,并使用Coredata保存了图像和照片标题。
@IBAction func saveBtn(_ sender: UIButton) {
checkFavorite(photoTitle: photoArrayFromSearchView[sender.tag].title)
if isAdded == false {
save(btnTag: sender.tag)
}
}
func save(btnTag:Int){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let favoritePhotos = FavoritePhotos(context: context)
downloadFavoriteData(btnTag: btnTag, favoritePhotos: favoritePhotos) { (dataDownloaded) in
if dataDownloaded {
do {
try context.save()
print("save successfully")
} catch {
print("fail to save")
}
}
}
}
我找不到按下按钮保存相对照片的方法,所以我使用button.tag = cell.item来实现。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! ResultCollectionViewCell
cell.BtnView.tag = indexPath.item
cell.photoTitle.text = photoArrayFromSearchView[indexPath.row].title
cell.photoImg.af_setImage(withURL: photoArrayFromSearchView[indexPath.row].photoURL)
return cell }
它有效,但这是问题所在。
我无法通过button.tag使用相同的方式删除项目。
项目被删除后,我的button.tag不会以某种方式重新加载。
它崩溃了。错误:索引超出范围。
因为button.tag没有重新加载,但是collectionView索引已经更改。
@IBAction func deleteBtn(_ sender: UIButton) {
let Index = IndexPath(row: sender.tag, section: 0)
deleteItem(btnTag: sender.tag)
fetch()
favoritePhotoCollection.deleteItems(at: [Index])
}
func deleteItem(btnTag:Int){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
context.delete(favoriteArray[btnTag])
do {
try context.save()
} catch {
print("delete fail")
}
}
func fetch(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequset = NSFetchRequest<FavoritePhotos>(entityName: "FavoritePhotos")
fetchRequset.returnsObjectsAsFaults = false
do {
favoriteArray = try context.fetch(fetchRequset)
} catch {
print("fail to fetch")
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return favoriteArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as!
FavoriteCollectionViewCell
cell.BtnView.tag = indexPath.item
cell.photoTitle.text = favoriteArray[indexPath.row].photoTitle
if let data = favoriteArray[indexPath.row].photoImg as Data? {
cell.photoImg.image = UIImage(data: data)
}else {
cell.photoImg.image = nil
}
return cell
}
有人可以告诉我如何解决此问题吗?
或者是使用CollcetionViewCell中的按钮删除或保存数据的更好方法。
要耐心阅读。
答案 0 :(得分:0)
它将不起作用,因为当回收视图回收时。所以那个标签就不会一样了。您可以做的就是分配一些独特的东西,例如可以使用保存标题作为标签,并尝试使用该标签进行保存和提取。
答案 1 :(得分:0)
问题是fetch
行。从CoreData 和中将其从数据源阵列中删除,但不要重新获取数据。
@IBAction func deleteBtn(_ sender: UIButton) {
let indexPath = IndexPath(row: sender.tag, section: 0)
photoArrayFromSearchView.remove(at: indexPath.row)
deleteItem(btnTag: sender.tag)
favoritePhotoCollection.deleteItems(at: [indexPath])
}
还有另一个不一致之处:有两个不同的数组favoriteArray
和photoArrayFromSearchView
答案 2 :(得分:0)
代替button.tag,您可以创建一个删除动作委托协议(具有deleteCell函数)。您的视图控制器应符合协议,并将自身分配给单元格。然后,视图控制器可以通过“ collectionView.indexPath(for:UICollectionViewCell)”找出项目的indexPath,然后在deleteCell函数的实现中删除该单元格。