swift - UICollectionView Cell 按钮长按手势返回 self 不断变化?

标签 swift uicollectionview swift-protocols uilongpressgesturerecogni

我有一个类似购物车页面的东西,它显示用户在 Collection View 中选择的产品,每个单元格都有 2 个链接到产品的按钮,这些按钮将增加/减少单例 cartManager 的产品数量。

到目前为止,一切正常,我使用协议(protocol)来确保我知道我要从中添加/减去产品的 Collection View 中的哪个产品。使用此代码:

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 委托(delegate)、数据源和自定义协议(protocol),并将所有单元格的委托(delegate)委托(delegate)给 cellForItem 中的 View Controller 。每次添加或减去产品时,我都会重新加载 Collection View ,以便在单元格标签上显示正确的数量。

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)
    }
}

但是,当我长按按钮时,其添加的项目混合在一起,调试消息显示我收到的 Collection View 单元格的索引按升序 0,1,2,3 上升,然后重复 0, 1,2,3(取决于 Collection View 单元格中有多少产品)

请问,有办法解决这个问题吗?当我长按时,我是否应该不重新加载 Collection View ?如果是,我该如何更新 UI 以通知用户。是否有其他方法可以解决该问题,或者我应该放弃长按的想法,只允许用户点击金额并进行编辑?

最佳答案

好的,找到解决方法了。在我实现了长按委托(delegate)之后,我将协议(protocol)拆分为两个额外的函数,一个用于长按开始/仍然按下时,另一个用于长按结束时。

func cartProductLongPlusStarted(_ sender: CartProductCell)
func cartProductLongMinusStarted(_ sender: CartProductCell)
func cartProductLongPlusEnded(_ sender: CartProductCell)
func cartProductLongMinusEnded(_ sender: CartProductCell)

但是,当长按处于事件状态时,我不会从 View Controller 更新 UI,我只是从单元格本身更新它们。单元格只会硬编码来更新 UI,并且只有当长按完成时, View Controller 才会再次更新 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)
    }
}

唯一的小问题是长按似乎更新太快,该值可能更新得太快,以至于用户无法在正确停止时使用react,有什么想法可以减慢长按函数调用的更新速度吗?

关于swift - UICollectionView Cell 按钮长按手势返回 self 不断变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55822445/

相关文章:

ios swift : return to previous view controller

ios - 为什么 NSFetchRequest 没有初始化?

ios - UICollectionView 数据源方法未被调用,但正在初始化中设置

swift - Swift 协议(protocol)可以是单例的吗?

ios - 扩展符合协议(protocol)的类?

ios - 缺少推送通知权利,我的应用程序不包含它

swift - 在 XCode 中编写模块化 UI 测试

ios - 如何更改 iOS 中网格和列表的 UICollectionView 布局

ios - UICollectionView 上的自动布局约束更改动画

Swift 类型删除尝试 : "Reference to invalid associated type"