ios - 在 Swift 中单击 CAShapeLayer 时检测触摸

标签 ios swift cashapelayer

我制作了一个可以在红色圆圈路径中拖动的蓝色球: enter image description here

拖动的功能很好用,但是!它在我点击屏幕的任何地方都有效,我想让它在我点击蓝色球时拖动。

到目前为止,这是我的代码:

override func viewDidLoad() {
        super.viewDidLoad()
circlePath2 = UIBezierPath(arcCenter: CGPoint(x: earthX,y: earthY), radius: CGFloat(10), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
        shapeLayer2.path = circlePath2.CGPath
        shapeLayer2.fillColor = UIColor.blueColor().CGColor
        shapeLayer2.strokeColor = UIColor.clearColor().CGColor
        shapeLayer2.lineWidth = 7
        view.layer.addSublayer(shapeLayer2)
        
        let dragBall = UIPanGestureRecognizer(target: self, action:#selector(ViewController.dragBall(_:)))
        view.addGestureRecognizer(dragBall)
}
@IBAction func dragBall(recognizer: UIPanGestureRecognizer) {
            let point = recognizer.locationInView(self.view)
            let earthX = Double(point.x)
            let earthY = Double(point.y)
            let midViewXDouble = Double(midViewX)
            let midViewYDouble = Double(midViewY)
            let angleX = (earthX - midViewXDouble)
            let angleY = (earthY - midViewYDouble)
            angle = atan2(angleY, angleX)
            let earthX2 = midViewXDouble + cos(angle)*100
            let earthY2 = midViewYDouble + sin(angle)*100
            circlePath2 = UIBezierPath(arcCenter: CGPoint(x: earthX2,y: earthY2), radius: CGFloat(10), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
            shapeLayer2.path = circlePath2.CGPath
}

我尝试将下面的代码添加到 dragBall 函数中,就像声明一样:(它检测用户是否恰好触摸了蓝色球)

if ((point.x >= circlePath2.currentPoint.x - circlePath2.bounds.width/2) && (point.y <= circlePath2.currentPoint.y + circlePath2.bounds.height/2)) && ((point.y >= circlePath2.currentPoint.y - circlePath2.bounds.height/2) && (point.y <= circlePath2.currentPoint.y + circlePath2.bounds.height/2)){

它奏效了,但只有当我的触摸没有离开蓝色球的位置时我才能拖动它,例如,如果我只想在我接触球时才开始接触球 - 我可以,但在我拖动时继续移动他在屏幕的其他地方 - 我不能。

快捷方式:仅当我触摸球时才开始拖动球,当我触摸到屏幕的任何位置时继续拖动。

最佳答案

在您的dragBall 函数中,读取您的手势识别器的state 属性。如果状态为 UIGestureRecognizerStateBegan 并且触摸在蓝色球内,则手势已正确启动,您可以允许后续手势影响球的位置,即使它们不在球内。

最好的方法可能是在创建符合 UIGestureRecognizerDelegate 的手势识别时,为手势识别分配一个 delegate,然后实现 gestureRecognizerShouldBegin:功能。在这个函数中,如果触摸不在蓝球内部,则返回false。

这是我与代表谈论的例子:

class MyClass: NSObject, UIGestureRecognizerDelegate {

  let ballView = UIView()

  func createRecognizer() {
      let recognizer = UIPanGestureRecognizer(target: self, action: #selector(MyClass.gestureRecognized(_:)))
      recognizer.delegate = self
      ballView.addGestureRecognizer(recognizer)
  }

  func gestureRecognized(recognizer: UIPanGestureRecognizer) {
      // update ball position
  }

  func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
      let location = gestureRecognizer.locationInView(ballView)
      return CGRectContainsPoint(ballView.bounds, location)
  }
}

关于ios - 在 Swift 中单击 CAShapeLayer 时检测触摸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37632440/

相关文章:

ios - 检测按下哪个按钮来打开此 View

ios - 如何以编程方式从 iOS 应用程序打开 Apple Watch 配套应用程序

ios - CAShapeLayer路径 Spring 动画不是 'overshooting'

ios - 动画 UIView 的 subview 在动画期间不保持其约束

ios - 在 Swift 中检测 CAShapeLayer 上的点击?

ios - 使用 UIButton 的 z 顺序将子层或 UIView 作为 subview 添加到顶部仍然位于 View 后面或看起来透明

ios - 更改处于选中状态的 UIButton 的颜色

业务分发的IOS Provisioning profile

ios - 无法使用类型为 (String, Int) Swift 2 的索引为类型 [(String, Int)] 的值下标

ios - 看看这段代码,让我知道是否有任何我可以更改的地方