UICollectionView 单元格按钮长按手势返回自我不断变化?
Posted
技术标签:
【中文标题】UICollectionView 单元格按钮长按手势返回自我不断变化?【英文标题】:UICollectionView Cell Button Long Press Gesture return self keep changing? 【发布时间】:2019-04-24 04:29:31 【问题描述】:我有一个类似于购物车页面的东西,它显示了用户在集合视图中选择的产品,每个单元格都有 2 个链接到产品的按钮,这些按钮将增加/减少单个 cartManager 的产品数量。
到目前为止,一切正常,我使用协议来确保我知道我正在从集合视图中添加/减去产品。使用此代码:
protocol CartProductButtonDelegate : class
func cartProductPlus(_ sender: CartProductCell)
func cartProductMinus(_ sender: CartProductCell)
class CartProductCell: UICollectionViewCell
//labels and image product details etc.
@IBOutlet weak var productMinusBtn: UIButton!
@IBOutlet weak var productPlusBtn: UIButton!
weak var delegate : CartProductButtonDelegate?
override func awakeFromNib()
super.awakeFromNib()
let tapPlusGesture = UITapGestureRecognizer(target: self, action: #selector(productPlusBtnTapped(_:)))
tapPlusGesture.numberOfTapsRequired = 1
self.productPlusBtn.addGestureRecognizer(tapPlusGesture)
let tapMinusGesture = UITapGestureRecognizer(target: self, action: #selector(productMinusBtnTapped(_:)))
tapMinusGesture.numberOfTapsRequired = 1
self.productMinusBtn.addGestureRecognizer(tapMinusGesture)
@objc func productMinusBtnTapped(_ sender: UITapGestureRecognizer)
delegate?.cartProductMinus(self)
@objc func productPlusBtnTapped(_ sender: UITapGestureRecognizer)
delegate?.cartProductPlus(self)
在我的 UIViewController 中,我添加了collectionview 委托、数据源和自定义协议,并将所有单元格委托给 cellForItem 中的 viewcontroller。每次我添加或减去产品时,我都会重新加载集合视图,以便在单元格标签上显示正确的数量。
func cartProductPlus(_ sender: CartProductCell)
guard let tappedIndexPath = self.cartCollectionView.indexPath(for: sender) else
debugPrint("GUARD BROKE GETTING INDEX PATH FOR PRODUCT PLUS TAPPED")
return
let product = self.productList[tappedIndexPath.item]
debugPrint("cart Product Plus on product name: \(product.name), index : \(tappedIndexPath.item)")
if let maxBought = Int(product.maxBought ?? "")
if cartManager.numberOfProductsInCart(product: product) < maxBought
cartManager.addProduct(product: product)
self.rearrangeArray()//this is to reload the collection view as well as update UI on cart and someother stuff
当我尝试使用现有逻辑为想要批量购买的人添加长按手势时出现问题。
我已经尝试过实现这个:
let longPressPlusGesture = UILongPressGestureRecognizer(target: self, action: #selector(productPlusLongPressed(_:)))
self.productPlusBtn.addGestureRecognizer(longPressPlusGesture)
@objc func productPlusLongPressed(_ sender: UILongPressGestureRecognizer)
if sender.state == .began || sender.state == .changed
delegate?.cartProductPlus(self)
但是,当我长按按钮时,它添加的项目混淆了,调试消息显示我收到的集合视图单元格的索引按升序 0、1、2、3 上升,然后重复 0, 1,2,3(取决于集合视图单元格中有多少产品)
那么问题来了,有没有办法解决这个问题?当我长按时我是否应该不重新加载集合视图,如果是这样,我如何更新 UI 以通知用户。有没有其他方法可以解决这个问题,还是我应该放弃长按的想法,只允许用户点击金额并进行编辑?
【问题讨论】:
您绝对需要避免在长按处于活动状态时重新加载集合视图,因为单元格的位置会四处移动,这只会令人困惑。 嗯,我已经尝试避免重新加载 collectionView 并为 longpress 创建单独的协议函数,而这些函数仅用于使用 reloadItems(at:) 重新加载单个项目。但是,长按会更新一次,在随后的函数调用之后,我无法获取单个索引路径,防护被打破。有什么想法吗? 在长按完成之前,您无法重新加载包含活动长按的单元格。 那么我将如何更新该单元格上金额的 UI? 【参考方案1】:好的,找到了解决方法。在我实现了长按委托后,我将协议拆分为两个额外的功能,一个用于长按开始/仍然按下,另一个用于长按结束。
func cartProductLongPlusStarted(_ sender: CartProductCell)
func cartProductLongMinusStarted(_ sender: CartProductCell)
func cartProductLongPlusEnded(_ sender: CartProductCell)
func cartProductLongMinusEnded(_ sender: CartProductCell)
但是,当长按处于活动状态时,我不会从视图控制器更新 UI,我只是从单元格本身更新它们。单元格只会硬编码以更新 UI,只有当长按完成时,视图控制器才会再次更新 UI。
@objc func productPlusLongPressed(_ sender: UILongPressGestureRecognizer)
if sender.state == .began || sender.state == .changed
delegate?.cartProductLongPlusStarted(self)
if var amount = Int(self.productCountLabel.text ?? "0")
if self.maxAmount != nil
if amount < self.maxAmount!
amount += 1
else
amount += 1
self.productCountLabel.text = String(amount)
else
delegate?.cartProductLongPlusEnded(self)
唯一的小问题是长按似乎更新得太快了,值可能更新得太快,以至于用户在正确停止时做出反应,有什么想法可以减慢长按函数调用的更新速度吗?
【讨论】:
以上是关于UICollectionView 单元格按钮长按手势返回自我不断变化?的主要内容,如果未能解决你的问题,请参考以下文章
无法通过移动它们来重新排列 UICollectionView 中的单元格?