Xcode & Swift - Detecting user touch of UIView inside of UIScrollView Xcode & Swift - Detecting user touch of UIView inside of UIScrollView ios ios

Xcode & Swift - Detecting user touch of UIView inside of UIScrollView


By setting userInteractionEnabled to NO for your scroll view, the view controller will start receiving touch events since UIViewController is a subclass of UIResponder. You can override one or more of these methods in your view controller to respond to these touches:

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

I created some example code to demonstrate how you could do this:

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


You can programmatically add a gesture recognizer as follows

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

However, this gesture recognizer won't work for you. UITapGestureRecognizer will only return for a tap, not a tap and hold, and UILongPressGestureRecognizer doesn't give information about location, so you want to use a UIPanGestureRecognizer. It continually tells you how far the touch has moved.

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

You can use the constant "translation" to move your object, it represents the distance the person has slid their finger. Use that plus the location of your bird to move the bird to a new point. You have to reset the translation to zero after this function is called.

Edit: With the format of your game, this code should be the best method.

So, all together, the code to find the location of your finger should be as follows.

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 is a CGPoint containing the location of the current touch, wherever the finger is slid to. As I do not know how you are creating the views to be avoided, you will have to use the y coordinate of currentLocation to determine the x boundaries of the views that are to be avoided at that y, and use < or > comparators to determine if the x boundary of the touch is inside either of those views.

Note: you have to declare location so it can be accessed in handlePan

var location : CGPoint = CGPointZero