在 UICollectionView 中删除单元格后,如何更新作为 UICollectionViewCell 一部分的按钮标签?
Posted
技术标签:
【中文标题】在 UICollectionView 中删除单元格后,如何更新作为 UICollectionViewCell 一部分的按钮标签?【英文标题】:How to update the button tag which is part of UICollectionViewCell after a cell is deleted in UICollectionView? 【发布时间】:2016-03-04 13:02:05 【问题描述】:这是一个困扰我很久的问题。 这是代码
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
collectionViewLove?.performBatchUpdates(() -> Void in
self.collectionViewLove?.deleteItemsAtIndexPaths([indexPath])
self.wishlist?.results.removeAtIndex(indexPath.row)
self.collectionViewLove?.reloadData(), completion: nil)
我在每个UICollectionViewCell
内都有一个按钮,单击它会删除它。我检索indexPath
的唯一方法是通过按钮标签。我已经在
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
但是,每次我删除时,第一次它会删除相应的单元格,而下一次它会删除我单击的单元格之后的单元格。原因是当我调用函数reloadData()
时我的按钮标签没有更新。
理想情况下,当我拨打 reloadData()
时,
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
应该被调用并更新每个单元格的按钮标签。但这并没有发生。有人解决吗?
编辑:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
collectionView.registerNib(UINib(nibName: "LoveListCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell")
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! LoveListCollectionViewCell
cell.imgView.hnk_setImageFromURL(NSURL(string: (wishlist?.results[indexPath.row].image)!)!, placeholder: UIImage(named: "preloader"))
let item = self.wishlist?.results[indexPath.row]
cell.layer.borderColor = UIColor.grayColor().CGColor
cell.layer.borderWidth = 1
cell.itemName.text = item?.title
cell.itemName.numberOfLines = 1
if(item?.price != nil)
cell.price.text = "\u20B9 " + (item?.price.stringByReplacingOccurrencesOfString("Rs.", withString: ""))!
cell.price.adjustsFontSizeToFitWidth = true
cell.deleteButton.tag = indexPath.row
cell.deleteButton.addTarget(self, action: "removeFromLoveList:", forControlEvents: .TouchUpInside)
cell.buyButton.tag = indexPath.row
cell.buyButton.backgroundColor = UIColor.blackColor()
cell.buyButton.addTarget(self, action: "buyAction:", forControlEvents: .TouchUpInside)
return cell
【问题讨论】:
删除单元格时只更新您的收藏视图 可以写你单元格的删除代码,这样我可以更好的回答你 我正在用self.collectionViewLove.reloadData()
更新它
你能不能为 cellForItemAtIndexPath 写代码
@MalavSoni 给你
【参考方案1】:
有几点:
您在cellForItemAtIndexPath
中做的工作太多——您真的希望它尽可能快。例如,您只需要为 collectionView 注册一次 nib--viewDidLoad()
是一个很好的地方。另外,您应该在单元格的prepareForReuse()
方法中设置单元格的初始状态,然后仅使用cellForItemAtIndexPath
来使用来自项目的自定义状态进行更新。
在删除完成之前,您不应重新加载数据。将 reloadData
移动到您的完成块中,以便删除方法完成并且视图有时间更新其索引。
但是,如果您一开始就不必致电reloadData
,那就更好了。您的实现将按钮的标签与 indexPath 相关联,但它们在不同的时间发生变异。将按钮的标签绑定到愿望清单项目 ID 怎么样。然后就可以根据ID查找合适的indexPath了。
修改后的代码看起来像这样(未经测试且未经语法检查):
// In LoveListCollectionViewCell
override func prepareForReuse()
// You could also set these in the cell's initializer if they're not going to change
cell.layer.borderColor = UIColor.grayColor().CGColor
cell.layer.borderWidth = 1
cell.itemName.numberOfLines = 1
cell.price.adjustsFontSizeToFitWidth = true
cell.buyButton.backgroundColor = UIColor.blackColor()
// In your UICollectionView class
// Cache placeholder image since it doesn't change
private let placeholderImage = UIImage(named: "preloader")
override func viewDidLoad()
super.viewDidLoad()
collectionView.registerNib(UINib(nibName: "LoveListCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell")
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! LoveListCollectionViewCell
cell.imgView.hnk_setImageFromURL(NSURL(string: (wishlist?.results[indexPath.row].image)!)!, placeholder: placeholderImage)
let item = self.wishlist?.results[indexPath.row]
cell.itemName.text = item?.title
if(item?.price != nil)
cell.price.text = "\u20B9 " + (item?.price.stringByReplacingOccurrencesOfString("Rs.", withString: ""))!
cell.deleteButton.tag = item?.id
cell.deleteButton.addTarget(self, action: "removeFromLoveList:", forControlEvents: .TouchUpInside)
cell.buyButton.tag = item?.id
cell.buyButton.addTarget(self, action: "buyAction:", forControlEvents: .TouchUpInside)
return cell
func removeFromLoveList(sender: AnyObject?)
let id = sender.tag
let index = wishlist?.results.indexOf $0.id == id
let indexPath = NSIndexPath(forRow: index, inSection: 0)
collectionViewLove?.deleteItemsAtIndexPaths([indexPath])
wishlist?.results.removeAtIndex(index)
【讨论】:
【参考方案2】:除非需要显示单元格,否则将数据存储在单元格中可能不是一个好主意。相反,您可以依靠UICollectionView
为您提供正确的indexPath
,然后使用它从您的数据源中删除并更新collectionview。
为此,请使用带有单元格的委托模式。
1.定义您的控制器/数据源应遵守的协议。
protocol DeleteButtonProtocol
func deleteButtonTappedFromCell(cell: UICollectionViewCell) -> Void
2.向您的自定义单元格添加一个委托属性,该属性将在删除操作时回调控制器。重要的是要将单元格作为self
传递给该调用。
class CustomCell: UICollectionViewCell
var deleteButtonDelegate: DeleteButtonProtocol!
// Other cell configuration
func buttonTapped(sender: UIButton)
self.deleteButtonDelegate.deleteButtonTappedFromCell(self)
3.然后在控制器中执行协议函数来处理删除动作。在这里,您可以从 collectionView 中获取项目的 indexPath,该 indexPath 可用于删除数据并从 collectionView 中删除单元格。
class CollectionViewController: UICollectionViewController, DeleteButtonProtocol
// Other CollectionView Stuff
func deleteButtonTappedFromCell(cell: UICollectionViewCell)
let deleteIndexPath = self.collectionView!.indexPathForCell(cell)!
self.wishList.removeAtIndex(deleteIndexPath.row)
self.collectionView?.performBatchUpdates( () -> Void in
self.collectionView?.deleteItemsAtIndexPaths([deleteIndexPath])
, completion: nil)
4.确保在配置单元格时设置了委托,以便委托回调到某个地方。
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
//Other cell configuring here
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("identifier", forIndexPath: indexPath)
(cell as! CustomCell).deleteButtonDelegate = self
return cell
【讨论】:
【参考方案3】:我遇到了类似的问题,我通过在完成块中重新加载集合视图找到了答案。
只需像这样更新您的代码。
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
collectionViewLove?.performBatchUpdates(
self.collectionViewLove?.deleteItemsAtIndexPaths([indexPath])
self.wishlist?.results.removeAtIndex(indexPath.row)
, completion:
self.collectionViewLove?.reloadData()
)
Nik 在UICollectionView Performing Updates using performBatchUpdates 中提到过
【讨论】:
以上是关于在 UICollectionView 中删除单元格后,如何更新作为 UICollectionViewCell 一部分的按钮标签?的主要内容,如果未能解决你的问题,请参考以下文章
如何删除 UICollectionView 中单元格之间的空间? [复制]