UISwipeGestureRecognizer diagonal swipe issue - ios

Well, I have some code to add 4 recognizers to a view, like this
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
for(int d = UISwipeGestureRecognizerDirectionRight; d <= UISwipeGestureRecognizerDirectionDown; d = d*2) {
UISwipeGestureRecognizer *sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
sgr.direction = d;
[self.view addGestureRecognizer:sgr];
}
[self restore];
[self populate];
[self displaymap];
}
and a recognizer like this
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer
{
printf("Guesture: %d\n", recognizer.direction);
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft)
{
printf("a\n");
[self move: 'a'];
}
else if (recognizer.direction == UISwipeGestureRecognizerDirectionRight)
{
printf("d\n");
[self move: 'd'];
}
else if (recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
printf("w\n");
[self move: 'w'];
}
else if (recognizer.direction == UISwipeGestureRecognizerDirectionDown)
{
printf("s\n");
[self move: 's'];
}
else if (recognizer.direction == (UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionUp))
{
printf("y\n");
[self move: 'd'];
}
}
The problem is, it never detects the up | right direction, anybody know a way to fix this?

That’s not how the direction property works. UISwipeGestureRecognizer only recognizes swipes in a single direction at a time. You’ll need to do something more complicated involving a UIPanGestureRecognizer and determining its direction from the result of its -translationInView: / -velocityInView: methods.

Related

Getting UIPanGesture and UISwipeGesture working together in the same direction

I've set up my UIView to call a method when the view is panned up and to call some other method when the view is swiped up. My pan works fine and I can keep my pan disabled if my velocity.y is above a certain limit, but I can never get the swipe action to work when my pan fails. I've tried playing around with the delegate methods without much luck. Looked over this solution but no luck: https://stackoverflow.com/a/21728621/1925859
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panRec.delegate = self;
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.delegate = self;
[panedView addGestureRecognizer:swipeRec];
[swipeRec requireGestureRecognizerToFail:panRec];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint velocity = [pan velocityInView:gestureRecognizer.view];
if (ABS(velocity.y) > 200)
{
NSLog(#"Swipe actiavted");
return NO;
}
}
return YES;
}
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"In Swipe");
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
panedView.frame =CGRectOffset( panedView.frame, 0, -1*self.view.bounds.size.height*.80);
}
}
If you remove your delegate method, add direction to the swipe and change the receiver of requireGestureRecognizerToFail then it will work. Note that pans must be way slower than sweeps in order to be recognized.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.direction = UISwipeGestureRecognizerDirectionUp;
[panedView addGestureRecognizer:swipeRec];
[panRec requireGestureRecognizerToFail:swipeRec];
}
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"In Swipe");
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
panedView.frame =CGRectOffset( panedView.frame, 0, -1*self.view.bounds.size.height*.80);
}
}
- (IBAction)handlePan:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"PAN");
}

remove gesture for UIButton

I'm using UIGestureRecognizer for pan, rotate, pinch. But i'm applying to whole view. I need to remove gesture for button other than subviews. But when i use pan the button also affecting. How to restrict button move from self.view. I used below code for UIPanGestureRecognizer.
UIPanGestureRecognizer *dbpan = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(ondbPan:)];
[self.view addGestureRecognizer:dbpan];
[closeButton removeGestureRecognizer:dbpan];
Pan:
- (void)ondbPan:(UIPanGestureRecognizer *)gesture
{
if ((gesture.state == UIGestureRecognizerStateChanged) ||
(gesture.state == UIGestureRecognizerStateEnded)) {
CGPoint offset = [gesture translationInView:self.view];
CGPoint center = gesture.view.center;
center.x += offset.x;
center.y += offset.y;
gesture.view.center = center;
[gesture setTranslation:CGPointZero inView:self.view];
}
}
Try with bellow code that delegate of UIGestureRecognizer return FALSE if that subview is kind of class UIButton Class. also set delegate dbpan.delegate = self; while you setting and add UIPanGestureRecognizer.
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIButton class]])
{
return FALSE;
}
else
{
return TRUE;
}
}
UPDATE:-
I dont Know why that not working at your end i test this creating one demo as well using this code:-
.h file
#interface myviewcontroller : UIViewController<UIGestureRecognizerDelegate>
and .m class
- (void)pan:(UIPanGestureRecognizer *)gesture
{
if ((gesture.state == UIGestureRecognizerStateChanged) ||
(gesture.state == UIGestureRecognizerStateEnded)) {
CGPoint location = [gesture locationInView:self.view];
[demoView setCenter:location];
}
}
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIButton class]])
{
return FALSE;
}
else
{
return TRUE;
}
}
- (void)viewDidLoad
{
UIPanGestureRecognizer *dbpan = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(pan:)];
dbpan.delegate=self;
[self.view addGestureRecognizer:dbpan];
[super viewDidLoad];
}
-(IBAction)B1called
{
NSLog(#"This is called button 1");
}
-(IBAction)B2called
{
NSLog(#"This is called button 2");
}
And it's Output is
On Swift:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (touch.view!.isKindOfClass(UIButton)) {
return false
}
return true
}
Note: Make sure UIGestureRecognizerDelegate is added and tapGesture.delegate = self on viewDidLoad().
Try this...
while (closeButton.gestureRecognizers.count) {
[closeButton removeGestureRecognizer:[closeButton.gestureRecognizers objectAtIndex:0]];
}

Move UITableView with UISwipeGestureRecognizer

I am trying to mix an UISwipeGestureRecognizer with an UITableView.
What I would like to do is, while I am doing the swipe gesture, move at the same time the UITableView outside the window and refresh the table data.
I am going to show you with images...
This is my view:
My View
And I would like to get something like this:
Desired View
I am able to move the table when the swipe gesture is ended, but not while I am doing the gesture, and that is what I want.
This is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
swipeToRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(changeToGroup:)];
[swipeToRight setDelegate:self];
[swipeToRight setDirection:UISwipeGestureRecognizerDirectionRight];
[[self table]addGestureRecognizer:swipeToRight];
swipeToLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(changeToContact:)];
[swipeToLeft setDelegate:self];
[swipeToLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[[self table]addGestureRecognizer:swipeToLeft];
}
- (void)changeToGroup:(UISwipeGestureRecognizer *)swipeGesture
{
NSLog(#"Right to group");
[self updateTableData]; //Here I move the table and update data.
[segmentedControl setSelectedSegmentIndex:0];
}
- (void)changeToContact:(UISwipeGestureRecognizer *)swipeGesture
{
NSLog(#"Left to contact");
[self updateTableData]; //Here I move the table and update data.
[segmentedControl setSelectedSegmentIndex:1];
}
I thought that I could do it with UIGestureRecognizerStateBegan, adding the animations inside that event, but I can't receive it...
Could anyone help me?
Thanks a lot!!.
Try this,
use UIPanGestureRecognizer
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(handlePan:)];
[recognizer setMaximumNumberOfTouches:1];
[recognizer setDelegate:self];
[[self table]addGestureRecognizer:recognizer];
and in
- (void) handlePan:(UIPanGestureRecognizer *)recognizer {
UIView *view = self.tableView;
if(recognizer.state == UIGestureRecognizerStateBegan) {
// remember where the pan started
//panGestureOrigin is a CGPoint variable
panGestureOrigin = view.frame.origin;
//optional to keep an enum to keep direction
//self.panDirection = MenuPanDirectionNone;
}
CGPoint translatedPoint = [recognizer translationInView:view];
if(translatedPoint.x > 20) {
//self.panDirection = MenuPanDirectionRight;
[self handleRightPan:recognizer];
} else if(translatedPoint.x < 0) {
//self.panDirection = MenuPanDirectionLeft;
[self handleLeftPan:recognizer];
}
}
- (void) handleRightPan:(UIPanGestureRecognizer *)recognizer {
//animate here
if(recognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"Right to group");
[self updateTableData]; //Here I move the table and update data.
[segmentedControl setSelectedSegmentIndex:0];
}
}
- (void) handleLeftPan:(UIPanGestureRecognizer *)recognizer {
// animate here
if(recognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"Left to contact");
[self updateTableData]; //Here I move the table and update data.
[segmentedControl setSelectedSegmentIndex:1];
}
}

Adding gesture recognizer control to JTRevealSideBarDemoV2

I am using JTRevealSideBarDemoV2 for the implementation of the side panels like facebook and Path application. I have configured it in every sense and just want to add one more feature into this library. What I want is to apply gesture recognizer control in this library just similar to facebook. can somebody help?
The link for downloading this library is:-https://www.cocoacontrols.com/controls/jtrevealsidebar
Thanks!
#wattson:- this is the code which I have added for implementing Gesture Recognizer. BBut it is behaving very abnormally. If you have downloaded the code for JTRevealSideBarDemoV2 then you can analyze the code which i have written for.
The code is:
(void)setUpGestures{
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(movePanel:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[self.view addGestureRecognizer:panRecognizer];
}
-(void)movePanel:(id)sender {
[[[(UITapGestureRecognizer*)sender view] layer] removeAllAnimations];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender
translationInView:self.view];
CGPoint velocity = [(UIPanGestureRecognizer*)sender velocityInView:[sender view]];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
//UIView *childView = nil;
if(velocity.x > 0) {
if (!JTRevealedStateRight) {
[self revealLeftSidebar:(UIPanGestureRecognizer *)sender];
}
} else {
if (!JTRevealedStateLeft) {
[self revealRightSidebar:(UIPanGestureRecognizer *)sender];
}
}
// Make sure the view you're working with is front and center.
//[self.view sendSubviewToBack:];
[[sender view] bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
}
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
if(velocity.x > 0) {
// NSLog(#"gesture went right");
} else {
// NSLog(#"gesture went left");
}
if (!_showPanel) {
[self revealLeftSidebar:(UIPanGestureRecognizer *)sender];
} else {
if (JTRevealedStateLeft) {
[self revealRightSidebar:(UIPanGestureRecognizer *)sender];
} else if (JTRevealedStateRight) {
[self revealLeftSidebar:(UIPanGestureRecognizer *)sender];
}
}
}
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateChanged) {
if(velocity.x > 0) {
// NSLog(#"gesture went right");
} else {
// NSLog(#"gesture went left");
}
// Are you more than halfway? If so, show the panel when done dragging by setting this
value to YES (1).
_showPanel = abs([sender view].center.x - self.view.frame.size.width/2) >
self.view.frame.size.width/2;
// Allow dragging only in x-coordinates by only updating the x-coordinate with
translation position.
[sender view].center = CGPointMake([sender view].center.x + translatedPoint.x, [sender
view].center.y);
[(UIPanGestureRecognizer*)sender setTranslation:CGPointMake(0,0) inView:self.view];
// If you needed to check for a change in direction, you could use this code to do so.
if(velocity.x*_preVelocity.x + velocity.y*_preVelocity.y > 0) {
// NSLog(#"same direction");
} else {
// NSLog(#"opposite direction");
}
_preVelocity = velocity;
}
}

ios swipe through vertical line

I'm trying to make a vertical line from the top of my main view to the bottom, and it will trigger an action when someone swipes and crosses this line from either direction. I've already tried creating a tall thin label and putting a swipe recognizer inside of this, but it does not work the way I want. It only detects a swipe when you start inside of the label and swipe but not if you start outside the label and cross through it.
Here is my code so far,
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(doSomething)];
swipe.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
swipe.numberOfTouchesRequired = 1;
[self.myLabel setUserInteractionEnabled:YES];
[self.myLabel addGestureRecognizer:swipe];
The easiest way is to use the touchesBegan: and touchesMoved: method on a UIView to decide if it's crossed the midway line. You would then just add a view (your line) on top of this view, and you may want to disable user interaction on your "line" view. BTW, a quick dirty way to create a line is to create a view that's 2px wide (or whatever width you want) and set it's background color to your "line" color...
You need to decide in touchesBegan: which side they started on, and then do something like this in touchesMoved::
- (void) touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event {
CGPoint tappedPt = [[touches anyObject] locationInView: self];
if (tappedPt.x > self.frame.width/2 && self.userStartedOnLeftSide)
// User crossed the line...
else if (tappedPt.x < self.frame.width/2 && !self.userStartedOnLeftSide)
// User crossed the line...
else
// You probably don't need this else, the user DID NOT cross the line...
}
Similarly, you could do this in a UIViewController with a swipe gesture recognizer something like this:
- (void)swipe:(UISwipeGestureRecognizer *)recognizer{
CGPoint point = [recognizer locationInView:[recognizer view]];
if (recognizer.state == UIGestureRecognizerStateBegan)
// The user began their swipe at point
else if (recognizer.state == UIGestureRecognizerStateEnded)
// The user ended their swipe at point
// Add some logic to decide if they crossed the line...
}
If you're just trying to detect left and right swipes, you can put it on your main view like so:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UISwipeGestureRecognizer *swipe;
swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipe.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipe];
swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipe.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipe];
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)gesture
{
NSLog(#"%d", [gesture numberOfTouches]);
if (gesture.direction == UISwipeGestureRecognizerDirectionLeft)
{
NSLog(#"LEFT");
}
if (gesture.direction == UISwipeGestureRecognizerDirectionRight)
{
NSLog(#"RIGHT");
}
}
If you wanted to really test to see if you crossed the midpoint, you could use aUIPanGestureRecognizer:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.view addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)]];
}
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
static CGPoint startLocation;
static BOOL startAtLeft;
CGPoint location = [gesture locationInView:gesture.view];
if (gesture.state == UIGestureRecognizerStateBegan)
{
startLocation = location;
startAtLeft = (location.x < (gesture.view.frame.size.width / 2.0));
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
BOOL nowAtLeft = (location.x < (gesture.view.frame.size.width / 2.0));
if (startAtLeft != nowAtLeft)
{
if (startAtLeft)
NSLog(#"swiped across midpoint, left to right");
else
NSLog(#"swiped across midpoint, right to left");
}
}
}
With the pan gesture, you can customize this to your heart's content (e.g. recognize gesture as soon as the user's finger crosses rather than waiting for them to end the gesture, etc.).

Resources