UITapGestureRecognizer - Detecting if there's a sprite at tap location (swift) - ios

I'm making an iOS game and need to know how to get the location of tap for uitapgesturerecognizer. I do NOT want to use touchesBegan, touchesEnded, etc. I also need to know how to check if a user double tapped the sprite node. I already have set up uitapgesturerecognizer's all I need to know is how to find the location of touch and see if it is the same location as a sprite node.
Any help is greatly appreciated!

Assuming your sprite is of a class that inherits from UIView (and I think they generally are) the handler function for the gesture recognizer should look like this.
func handleDoubleTap(gestureRecognizer: UITapGestureRecognizer) {
let tapLocation = gestureRecognizer.location(in: gestureRecognizer.view)
if mySprite.frame.contains(tapLocation){
print("tapped")
}
}

Related

Scenekit gesture recognizer and overlaySKScene touches

Currently working on a game with scene kit in swift. I've got a joystick added to a SKScene, which is then attached to my scene kit game scene. Typical HUD overlay for controls.
let hudScene = SKScene(size: view.frame.size)
scnView.overlaySKScene = hudScene
I have also added a joystick to hudScene and want to add some buttons. Now, all of this works fine until I add a gesture recognizer to my main game scene. Once I do, all tap interaction with the hudScene is completely ignored. Even if I tap on the joystick and log what node was tapped at that location, it gives me the node in my game scene and completely ignores the nodes in hudScene.
Can anybody provide any insight into why this is happening?
For reference, the touch events for the joystick are implemented from this library, and my gesture recognizer is implimented like this:
let touchDownRec = UILongPressGestureRecognizer(target: self, action: #selector(didTouchDown(_:)) )
touchDownRec.minimumPressDuration = 0
touchDownRec.numberOfTouchesRequired = 1
scnView.addGestureRecognizer(touchDownRec)
I had the same problem... you have to replace the touchesBegan with a TapGesture, or replace the UILongPressGestureRecognizer with touchesEnded, but is more precise the first option.

Disable camera panning in SceneKit

If I am using the default camera control in SceneKit, is there a way to disable the two fingered pan function and leave the others as they are?
I want users to be able to rotate and zoom an object, but not move it at all.
The sceneView already has a UIPanGestureRecognizer attached.
If you modify its maximumNumberOfTouches to be 1, you can disable the pan gesture.
for reco in sceneView.gestureRecognizers! {
if let panReco = reco as? UIPanGestureRecognizer {
panReco.maximumNumberOfTouches = 1
}
}
No. You'll have to make your own camera and use gesture recognizers.

Please help me get a grip on UIGestureRecognizers in swift

I am having the hardest time figuring out gesture recognizers and such on iOS. Unfortunately a lot of the documentation by apple appears to be in Objective-C and/or it doesn't give you examples that show what values can go in. Could you show me some examples of how to the the following things.
Get the current position of each touch event on the screen. If the finger isn't down then return false.
Make a direction recognizer other then the 4 main directions. Currently my code looks like this
var leftSwipe = UISwipeGestureRecognizer(target: self, action: Selector("HandleSwipes:"))
leftSwipe.direction = .Left
view.addGestureRecognizer(leftSwipe)
However what if I wanted to detect diagonal movement? Their isn't a .Diagonal. So the detection of a gesture works in the direction (0.5, 0.5).
Going back to the code I put before I have a function that I check the direction in
func HandleSwipes(sender: UISwipeGestureRecognizer) {
if (sender.direction == .Left) {
Label.text = "Left"
}
}
What if I want this swipe to only work for the 2nd finger down? Also how would I get the ending, and starting position of that gesture? (preferably inside of that function)
How can I find out how long it has taken the finger to do the gesture (getting from point A to point B).
I am not that familiar with swift, but in objective-c, this is how you will obtain the current position of a touch event.
CGPoint _originalCenter;
-(void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
// if the gesture has just started, record the current centre location
_originalCenter = self.center;
}
Hope this helps answer the first part of your question.

Press And Hold iPhone Screen

So I am working on an app for an iPhone and I need to detect if the player is holding the screen and I need to get the location of where they are pressing.
Originally I was using the touchesBegin function but that is only called when the screen is touched a new time. Is there a way that I can modify this to be called more often, like every time the the update function is called?
Another thing I looked into was the UILongGesture stuff, but I couldn't get the location of where it was pressed.
Any help/advice to figuring this out would be greatly appreciated.
I am being specific here on your question about how to get the location of where user tap,
- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
CGPoint touchPoint = [tapRecognizer locationInView: _tileMap] //locationInView is the method you need to try
}
Secondly, UIGestureRecognizer also gives you the state which may be useful in your case
UIGestureRecognizerStateBegan UIGestureRecognizerStateChanged
UIGestureRecognizerStateEnded
and so on.
Hope this helps
You were on the right track - are you using multitouch?
If not, all you need to do is set a variable when the user touches the screen, then clear that variable on the touches ended function. Using the update function would work but is a super inefficient way of doing it
I'm assuming you want something to happen when they keep their finger on the screen. You could schedule an event in say 2 seconds when they touch the screen, and then if they release the screen before that you just cancel the event.
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)
}
This code finds the initial location of the touch, and then the new location whenever the touch is moved. However, no code will be called without using the touchesEnded method. I can't give you much more without knowing how you intend to use the touch.

How to prefer tap gesture over draw gesture?

In my view I'm overriding all the "touches*" methods to let the user draw on the screen. I'm recording the locations.
In addition I have two gesture recognizers on my view to detect single tap and double tap.
If I now move my finger just a little bit and short enough, I will be recording a small "draw" gesture. However when raising the finger, an additional tap gesture will be triggered.
By trial and error I could possibly figure out a minimum time and movement threshold but I'm sure there are smarter ways?
I need to know after how much movement and/or it is save to assume that no tap gesture will trigger.
You can avoid tap gestures. Instead of that you can recognize taps in touch events itself.
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
if(touches.count == 1)
{
if([[touches anyObject] tapCount] == 1)
{
// Do the action here for single tap
}
else if([[touches anyObject] tapCount] == 2)
{
// Do the action here for double tap
}
}
}
And you have to set a global bool variable for check whether user moved the finger on the screen.
BOOL _isMoved;
And make it TRUE in the touch move event
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
_isMoved = YES;
}
Before recording the track, you check whether this flag is TRUE or not? And also dont forget to make the flag to FALSE after saving the track
Hope this will help you :)

Resources