I am creating a game, similar to Flappy Bird but the user holds their finger on the screen and dodges the obstacles, rather than tapping to make the bird fly.
I am doing this by having a UIScrollView, in which UIView's are used as obstacles. When the user touches a UIView, the game is over.
How do I detect the users touch of a UIView from within a UIScrollView? I am using Swift with Xcode Beta 4.
EDIT: This is screenshot of the game
As you can see, the user moves their finger between the grey blocks (UIViews) as they scroll up.
Xcode provides developers a unified workflow for user interface design, coding, testing, and debugging. The Xcode IDE combined with the Swift programming language make developing apps easy and fun. To test or run applications on an iPhone, iPad, Apple TV, or Apple Watch all you need is a free Apple ID.
Xcode is a complete developer toolset for creating apps for Mac, iPhone, iPad, Apple Watch, and Apple TV. Xcode brings user interface design, coding, testing, debugging, and submitting to the App Store into a unified workflow.
Given that Xcode works only on macOS, a solution to get Xcode on Windows would be to install macOS on a Windows PC by means of a virtualization app such as VMware or VirtualBox. Using a virtualization platform provides users with the full functionality of Xcode on your Windows machine.
Xcode only runs on a mac.
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With