Xcode& Swift - 在UIScrollView中检测UIView的用户触摸

时间:2014-07-31 14:37:42

标签: ios xcode uiview uiscrollview swift

我正在创建一个游戏,类似于Flappy Bird,但用户将手指放在屏幕上并躲过障碍物,而不是轻拍以使鸟儿飞翔。

我这样做是通过使用UIScrollView,其中UIView被用作障碍物。当用户触摸UIView时,游戏就结束了。

如何在UIScrollView中检测用户对UIView的触摸?我正在使用Swift和Xcode Beta 4。

编辑:这是游戏的截图

This is screenshot of the game

如您所见,用户在向上滚动时会在灰色块(UIViews)之间移动手指。

2 个答案:

答案 0 :(得分:49)

通过为滚动视图设置userInteractionEnabledNO,视图控制器将开始接收触摸事件,因为UIViewControllerUIResponder的子类。您可以在视图控制器中覆盖这些方法中的一个或多个以响应这些触摸:

  • touchesBegan:withEvent:
  • touchesMoved:withEvent:
  • touchesEnded:withEvent:
  • touchesCancelled:withEvent:

我创建了一些示例代码来演示如何执行此操作:

class ViewController: UIViewController {
    @IBOutlet weak var scrollView: UIScrollView!

    // This array keeps track of all obstacle views
    var obstacleViews : [UIView] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create an obstacle view and add it to the scroll view for testing purposes
        let obstacleView = UIView(frame: CGRectMake(100,100,100,100))
        obstacleView.backgroundColor = UIColor.redColor()
        scrollView.addSubview(obstacleView)

        // Add the obstacle view to the array
        obstacleViews += obstacleView
    }

    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
        testTouches(touches)
    }

    override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
        testTouches(touches)
    }

    func testTouches(touches: NSSet!) {
        // Get the first touch and its location in this view controller's view coordinate system
        let touch = touches.allObjects[0] as UITouch
        let touchLocation = touch.locationInView(self.view)

        for obstacleView in obstacleViews {
            // Convert the location of the obstacle view to this view controller's view coordinate system
            let obstacleViewFrame = self.view.convertRect(obstacleView.frame, fromView: obstacleView.superview)

            // Check if the touch is inside the obstacle view
            if CGRectContainsPoint(obstacleViewFrame, touchLocation) {
                println("Game over!")
            }
        }
    }

}

答案 1 :(得分:14)

您可以通过编程方式添加手势识别器,如下所示

var touch = UITapGestureRecognizer(target:self, action:"action")
scrollView.addGestureRecognizer(touch)

然而,这个手势识别器不会为你工作。 UITapGestureRecognizer仅返回点击,而不是点按并保持,UILongPressGestureRecognizer不提供有关位置的信息,因此您想要使用UIPanGestureRecognizer。它会不断告诉你触摸的移动距离。

var touch = UIPanGestureRecognizer(target:self, action:"handlePan")
scrollView.addGestureRecognizer(touch)

@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    recognizer.setTranslation(CGPointZero, inView: self.view)
}

你可以使用常数"翻译"移动你的物体,它代表了人滑动手指的距离。使用它加上你的鸟的位置将鸟移动到一个新的点。调用此函数后,必须将转换重置为零。

编辑:使用您的游戏格式,此代码应该是最好的方法。

所以,总之,找到手指位置的代码应如下所示。

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInView(yourScrollView)
    }
}


@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(self.view)
    var currentLocation : CGPoint = CGPointMake(location.x+translation.x, location.y+translation.y)
    recognizer.setTranslation(CGPointZero, inView: self.view)
}

currentLocation是一个CGPoint,包含当前触摸的位置,无论手指滑动到哪里。由于我不知道如何创建要避免的视图,因此必须使用currentLocation的y坐标来确定在该y处要避免的视图的x边界,并使用<或者>比较器,用于确定触摸的x边界是否在这些视图中。

注意:您必须声明位置,以便可以在handlePan

中访问它
var location : CGPoint = CGPointZero