【问题标题】:gestureRecognizerShouldBegin on Subview Blocking Gestures on Parent CollectionViewgestureRecognizerShouldBegin on Subview Blocking Gestures on Parent CollectionView
【发布时间】:2021-02-02 04:42:41
【问题描述】:

我在使用以下子视图阻止其父视图上的手势时遇到问题:

class Circle: UIControl, UIGestureRecognizerDelegate {
    
    let circle = CAShapeLayer()
    let radius: CGFloat = 15
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let circleCenter = CGPoint(x: self.frame.midX, y: self.frame.midY)
        let path = UIBezierPath(arcCenter: circleCenter, radius: radius, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
        circle.path = path.cgPath
        circle.frame = self.bounds
        layer.addSublayer(circle)
        
        let gesture = UITapGestureRecognizer(target: self, action: #selector(Circle.handleTap(_:)))
        addGestureRecognizer(gesture)
    }
    
    @objc func handleTap(_ selector: Any) {
        print("Here")
    }
    
    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let location = gestureRecognizer.location(in: self)
        let center = circle.position
        let circleFrame = CGRect(x: center.x - radius, y: center.y - radius, width: radius * 2, height: radius * 2)
        return circleFrame.contains(location)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我在UICollectionViewController(启用分页和全屏单元格)和UICollectionViewCell 的以下子类中包含了上面的这个圆形视图,如下面的代码所示:

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    
    let cellId = "cell"
    let dataSource: [UIColor] = [.blue, .purple, .brown, .green, .red]

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.isPagingEnabled = true
        collectionView.register(CellSubclass.self, forCellWithReuseIdentifier: cellId)
    }
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CellSubclass
        cell.backgroundColor = dataSource[indexPath.item]
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }
}

class CellSubclass: UICollectionViewCell {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let circle = Circle(frame: self.bounds)
        addSubview(circle)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我希望仅在点击圆圈时处理子视图 Circle 上的手势。 (在我的用例中,圆圈将围绕屏幕移动。这是一个简化的示例)。这段代码可以达到这个目的,但是 Circle 上的 gestureRecognizerShouldBegin(_:) 方法会阻止父视图的手势,并且不允许我在集合视图的单元格页面中滑动。

当我删除该方法时,我可以按预期在单元格中滑动。我不确定为什么子视图上的手势方法会以这种方式传播以影响其父视图,但我已尝试添加该方法

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool

两个类都返回 true,但没有成功。任何有助于了解正在发生的事情并解决此问题的帮助将不胜感激。

【问题讨论】:

    标签: ios swift xcode uikit


    【解决方案1】:

    希望有人会发现我如何解决这个问题很有帮助。我最初认为处理此问题的最佳方法是使用gestureRecognizerShouldBegin(_:) 方法,但使用全屏单元格时,该方法会阻止其他手势。允许我完成我想做的事情的方法是使用gestureRecognizer(_:shouldReceive:) 方法将所需的触摸区域过滤到我正在创建的识别器中。如下:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        let location = touch.location(in: self)
        let center = circle.position
        let circleFrame = CGRect(x: center.x - radius, y: center.y - radius, width: radius * 2, height: radius * 2)
        let status = circleFrame.contains(location)
        return status
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2019-01-02
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多