I want to handle in superview a touch event when there are two touches that land on different subviews.
Can I do it somehow by adding UITapGestureRecognizer with numberOfTouchesRequired =2; with a target self to a subviews?
Or I need to go something more complicated?
You could try something like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = touches.anyObject;
CGPoint referencePoint = [touch locationInView:self.view];
if([touch tapCount] == 2){
//Test touch coordinates to see if theres one in each view
}
Related
I am using a UISwipeGestureRecogizer to swipe left and right by using UISwipeGestureRecognizerDirectionRight and UISwipeGestureRecognizerDirectionLeft and its working totally fine but the default swipe is too sensitive, its just a little bit more than a tap.
Is there any way by which I can make it work like when a scrollView works when its paging enable property is true that till the user doesnt lifts its finger up, its doesnt work.
It will be fine if the view doesn't move with the finger moving, and only work when a left or right gesture is performed and the finger is lifted. Thanks.
A UISwipeGestureRecognizer will not give you any option to change the sensitivity or any other aspect of the swipe. To obtain more control over the swipe, you could use one among the following:
UIPanGestureRecognizer
Here is something to try with UIPanGestureRecognizer:
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer{
CGPoint velocity = [gestureRecognizer velocityInView:yourView];
if(velocity.x > 0){
//Right gesture
}else{
//Left gesture
}
}
UIResponder
All UIViews inherit from UIResponder, so you can use the touchesBegan, touchesMoved and touchesEnded method for calculating the touch. Try something like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [touches anyObject];
start = [touch locationInView:self.view];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint end = [touch locationInView:self.view];
//Compare start and end points here.
}
I have to do some "snap to grid" behaviour,
I have a dragging image "sprite", but I need to "snap" this sprite to a certain button if touches go on top of that button,
so how can i know if touchesEnded is on top of a certain button,
here my code, but i dont know when touches where ended on top of butotn
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touched = [[event allTouches] anyObject];
CGPoint location = [touched locationInView:touched.view];
CGRect recta = touched.view.frame;
if (CGRectIntersectsRect(recta, self.button_1.frame)) {
DLog(#"intersected");
}
}
So this is not happening,
can it be done?
or do i have to check the X and Y position of finishing touch against the button frame X and Y position by my self?
cheers
touched.view is the view on which the touch started. You want to find out if the location where the touch ended is on top of a specific button. You can do this by checking if the location of the touch relative to the button is within the button's bounds.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touched = [[event allTouches] anyObject];
CGPoint locationRelative = [touched locationInView:self.button_1];
if (CGRectContainsPoint(self.button_1.bounds, locationRelative)) {
DLog(#"on top of button_1");
}
}
You can use CGRectIntersectsRect, which returns YES, if the two rectangles your pass to it intersect.
I have been trying to implement a method where the user can press down the play button, it then changes the texture to the pressed down image. Then, if the user decides not to continue with their action. Such as starting the game. They can then simply drag out of the sprite's frame/body which will then no longer detect the touch as one which will start the action.
The problem with this implementation is that I can't make the touch on the button cancel if the user drags outside of the play button's sprite frame.
The code you will see below doesn't have the transition between the scenes, as I'd like to test the button's usability before having to always quit the application to try the button.
Also, I have declared the majority of objects in the .h file.
Code from MenuScene.m:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//Touch detection declaration
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
touchNode = [self nodeAtPoint:touchLocation];
if([touchNode.name isEqualToString:#"playButton"]){
[playButtonSprite runAction:changePlayButtonTextureON];
}else{}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
if ([touchNode.name isEqualToString:#"playButton"]) {
[playButtonSprite runAction:changePlayButtonTextureOFF];
}
}
I would also like to know if there is an alternative method to detecting if the touch is on the play button sprite node. Though, this may be solved when a solution is found for the previous issue I have mentioned.
The best way to handle this would be to subclass SKSpriteNode to handle touches on it's own. You can see such an implementation in this project on GitHub. It cancels the touch when the touch goes out of the node's bounds.
The existing code you have posted is good as the code will not get called when the touch ends out of the play button's bounds.
In your case, since you are handling the touches from the scene itself, you can explicitly set the playButton's texture whenever the touch is detected outside the node's bounds.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
touchNode = [self nodeAtPoint:touchLocation];
if(![touchNode.name isEqualToString:#"playButton"]){
[playButtonSprite runAction:changePlayButtonTextureOFF];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//Touch detection declaration
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
touchNode = [self nodeAtPoint:touchLocation];
if([touchNode.name isEqualToString:#"playButton"]){
[playButtonSprite runAction:changePlayButtonTextureON];
playButtonSprite.isON = YES;
}else{}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (playButtonSprite.isON) {
if ([touchNode.name isEqualToString:#"playButton"]) { // The user really wants to play!
[self startPlaying];
}
[playButtonSprite runAction:changePlayButtonTextureOFF];
playButtonSprite.isON = NO;
}
}
Where changePlayButtonTextureON also sets playButtonSprite.isON to YES, and vise versa.
You will want to make a subclass of SKSpriteNode for playButtonSprite, and add that boolean property isON there.
Can't seem to find an answer to this one anywhere.
My game starts when the user touches the screen, there is a path that the finger must stay within, if it touches/intersects the edges then I want it to run the method [self gameover].
The edge will be a UIImageView.
Thanks everyone.
I hope you have overridden the touches moved event. check either the user touch intersects your image view like below.
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point =[touch locationInView:self.view];
if (CGRectContainsPoint(self.imageView.frame, point))
{
//Intersects
[self gameOver];
}
}
I want to shift the position of some UILabels when the user swipes the screen--specifically, move them the same distance the user swiped their finger.
How would I go about detecting and implementing this?
Thanks
Override touchesBegan:withEvent and touchesMoved:withEvent:. Keep track of the starting location in touchesBegan:withEvent. If repeated calls to touchesDragged (it is called while the drag is happening) show that you are moving fast enough for the action to be a swipe versus just a drag, use the difference between the starting location and the current touch location to animate changing the UILabels.
You can do that by using following methods for UIView.
In touchesBegan you should store the position where the user first touches the screen. So you can identify the left or right swipe when touches ends.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
self.startPoint = [touch locationInView:self];
}
Record the final position on touchesEnded method. By comparing this two positions you can determine the direction of movement.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint endPosition = [touch locationInView:self];
if (startPoint.x < endPoint.x) {
// Right swipe
} else {
// Left swipe
}
}
I hope this helps.