Adding swipe gesture recognizer to DetailViewContoller - ios

I have simple xcode project just made from "Master-Detail Application" template, for iPad. When device is in Portrait orientation, master view is hidden and when you swipe right on detail view, master view will show up. Now, i want to add right swipe gesture recognizer to detail view, like that:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandler)];
[self.view addGestureRecognizer:gestureRecognizer];
}
-(void)swipeHandler{
NSLog(#"SWIPE");
}
But this code causes that when i swipe on detail view, "SWIPE" log appears in console, but master view doesn't show up.
How to add right swipe gesture recognizer to detail view, so it wont prevent master view to show up and my handler for recognizer will work?
Thanks in advance.
EDIT. I want my right swipe recognizer handler to work simultaneously with this built in one, which shows up master view, but that following code isn't a solution for this specific situation:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}

you should set the direction for the swipe in order to add the right swipe
UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandler:)];
[gestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:gestureRecognizer];
and your swipe handler might look like
-(void)swipeHandler:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
}

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRecognizer:)];
recognizer.direction = UISwipeGestureRecognizerDirectionRight;
recognizer.delegate = self;
[self.view addGestureRecognizer:recognizer];
}
- (void)swipeRecognizer:(UISwipeGestureRecognizer *)sender {
if (sender.direction == UISwipeGestureRecognizerDirectionRight){
[UIView animateWithDuration:0.3 animations:^{
CGPoint Position = CGPointMake(self.view.frame.origin.x + 100.0, self.view.frame.origin.y);
self.view.frame = CGRectMake(Position.x , Position.y , self.view.frame.size.width, self.view.frame.size.height);
[self.navigationController popViewControllerAnimated:YES];
}];
}
}

Try This
//Right Swipe
UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandlerRight:)];
[gestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:gestureRecognizer];
//Left Swipe
UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandlerLeft:)];
[gestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:gestureRecognizer];
call method
-(void)swipeHandlerRight:(id)sender
{
//Your ViewController
}
-(void)swipeHandlerLeft:(id)sender
{
//Your ViewController
}

This works. It pushes the view controller from the navigationController.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UISwipeGestureRecognizer *gestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandler:)];
[self.view addGestureRecognizer:gestureRecognizer];
}
-(IBAction)swipeHandler:(UISwipeGestureRecognizer *)sender
{
NSLog(#"SWIPE");
UIViewController *tb = [[DetailViewController alloc] init];
tb = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
[self.navigationController pushViewController: tb animated:YES];
}
Then be sure to go to storyboard (or you could also do this manually) - click on the Detail View Controller and give the View controller the Identity: DetailViewController

swift 4.0
Step 1: Add swipe Gesture(s) in viewDidLoad() method.
override func viewDidLoad() {
super.viewDidLoad()
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
swipeLeft.direction = .left
self.view.addGestureRecognizer(swipeLeft)
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
swipeRight.direction = .right
self.view.addGestureRecognizer(swipeRight)
}
Step 2: Check the gesture detection in handleGesture() method
#objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
if gesture.direction == UISwipeGestureRecognizerDirection.right {
print("Swipe Right")
}
else if gesture.direction == UISwipeGestureRecognizerDirection.left {
print("Swipe Left")
}
}

Related

How to implement Swipe and Hold gesture recognizer in Objective-C?

I am working on an application which works like a remote control of different devices like Game Console, Set-top Box, etc.
Application contains different type of controls like gesture and buttons to perform events as remote.
Single gesture view contains multiple gesture recognizer as follow:
1 finger Tap using UITapGestureRecognizer
2 finger Tap using UITapGestureRecognizer
1 finger swipe using UISwipeGestureRecognizer
2 finger swipe using UISwipeGestureRecognizer
My requirement is to implement 1 finger Swipe gesture recognizer along with hold event. So, that will continue my swipe action until user will not remove its finger from the view.
I have tried UILongPressGestureRecognizer after UISwipeGestureRecognizer but this didn’t work for me because it is executing along with Swipe movement. And I want this after Swipe end, but finger will not remove.
My code snippet :
-(void) gestureView:(UIView*)viewGesture {
UISwipeGestureRecognizer *swipeGestureSingleRight;
UISwipeGestureRecognizer *swipeGestureSingleLeft;
UISwipeGestureRecognizer *swipeGestureSingleUp;
UISwipeGestureRecognizer *swipeGestureSingleDown;
swipeGestureSingleUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleUp setDelegate:self];
[swipeGestureSingleUp setDirection:(UISwipeGestureRecognizerDirectionUp)];
[swipeGestureSingleUp setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleUp];
swipeGestureSingleDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleDown setDelegate:self];
[swipeGestureSingleDown setDirection:(UISwipeGestureRecognizerDirectionDown)];
[swipeGestureSingleDown setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleDown];
swipeGestureSingleRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleRight setDelegate:self];
[swipeGestureSingleRight setDirection:(UISwipeGestureRecognizerDirectionRight)];
[swipeGestureSingleRight setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleRight];
swipeGestureSingleLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleLeft setDelegate:self];
[swipeGestureSingleLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[swipeGestureSingleLeft setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleLeft];
longPressGestureOnSwipe = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGesture_Handle:)];
longPressGestureOnSwipe.minimumPressDuration = 0.03;
longPressGestureOnSwipe.delegate = self;
[viewGesture addGestureRecognizer:longPressGestureOnSwipe];
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
- (void)swipeGestureSingle_Handle:(UISwipeGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
singleTouchSwipeSenderDirection = sender.direction;
isSwipeEnd = true;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
-(void)longPressGesture_Handle:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (isSwipeEnd) {
[super touchesBegan:touches withEvent:event];
} else {
return;
}
}
Please suggest me correction or solution for my requirement.
Thanks in advance!

Adding both short long gestures in same view with proper differentiation

I am working on app in which I want both short long gesture in same view, I added but issue is I'm facing is that short gesture end always call, Need your help how to do that in right way. Below is my code.
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longGestureOnFormFields:)];
longGesture.minimumPressDuration = 1.0f;
[longGesture setDelegate:self];
[self addGestureRecognizer:longGesture];
UILongPressGestureRecognizer *shortGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(shortGesture:)];
shortGesture.minimumPressDuration = 0.1f;
[shortGesture setDelegate:self];
[self addGestureRecognizer:shortGesture];
- (void)longGestureOnFormFields:(UIGestureRecognizer*) recogniser
{
if (recogniser.state == UIGestureRecognizerStateEnded ) {
}
- (void)shortGesture:(UIGestureRecognizer*) recogniser
{
if (recogniser.state == UIGestureRecognizerStateEnded ) {
}
You can manage that by using one UITapGestureRecognizer like,
self.view.userInteractionEnabled = YES;
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longGestureOnFormFields:)];
longGesture.minimumPressDuration = 1.0f;
[longGesture setDelegate:self];
[self.view addGestureRecognizer:longGesture];
UITapGestureRecognizer *recog = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(testm)];
[self.view addGestureRecognizer:recog];
and your methods smething like,
-(void)testm{
NSLog(#"tap");
}
-(void)longGestureOnFormFields : (UILongPressGestureRecognizer*)sender{
if (sender.state == UIGestureRecognizerStateEnded ) {
NSLog(#"long press gesture");
}
}
I have added gesture recognizer in viewDidload i.e in viewcontroller so i have add it to self.view if you have subclass UIVIew and adding this to that view then add it on self like [self addgesture...] as shown in question!

Using AMSlideMenu, re-enabling swipe gesture

Need help using the AMSlideMenu from https://github.com/SocialObjects-Software/AMSlideMenu
In a project I'm creating I needed to disable the AMSlideMenu swiping so I could use the UISwipeGestureRecognize to perform another action.
The main swiping has been disabled [self disableSlidePanGestureForLeftMenu]; and the menu is accessible by pressing the menuBtn, but I would like to use UISwipeGestureRecognizer which AMSlideMenu seems to be disabling.
Any ideas on how I could regain the UISwipeGestureRecognizer for my project?
Thank you!
- (void)viewDidLoad
{
[super viewDidLoad];
[self disableSlidePanGestureForLeftMenu];
UIButton *menuBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[menuBtn addTarget:self
action:#selector(menuButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:menuBtn];
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action: #selector(swipeRecognized:) ];
[leftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:leftSwipe];
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action: #selector(swipeRecognized:) ];
[rightSwipe setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:rightSwipe];
}
- (void)menuButtonTapped:(id)sender
{
[self.mainSlideMenu openLeftMenu];
}
-(void) swipeRecognized:(UISwipeGestureRecognizer *)swipe {
int pageNum;
switch (swipe.direction)
{
case UISwipeGestureRecognizerDirectionLeft:{
pageNum++;
break;
}
case UISwipeGestureRecognizerDirectionRight:{
pageNum--;
break;
}
default:
break;
}
}
Change gesture in Table view
- (void)viewDidLoad
{
[super viewDidLoad];
[self disableSlidePanGestureForLeftMenu];
UIButton *menuBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[menuBtn addTarget:self
action:#selector(menuButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:menuBtn];
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action: #selector(swipeRecognized:) ];
[leftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.tableView addGestureRecognizer:leftSwipe];
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action: #selector(swipeRecognized:) ];
[rightSwipe setDirection:UISwipeGestureRecognizerDirectionRight];
[self.tableView addGestureRecognizer:rightSwipe];
}
- (void)menuButtonTapped:(id)sender
{
[self.mainSlideMenu openLeftMenu];
}
-(void) swipeRecognized:(UISwipeGestureRecognizer *)swipe {
int pageNum;
switch (swipe.direction)
{
case UISwipeGestureRecognizerDirectionLeft:{
pageNum++;
break;
}
case UISwipeGestureRecognizerDirectionRight:{
pageNum--;
break;
}
default:
break;
}
}
And now Just only Add an delegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
You need to stop left/right pan gesture from left menu controller class.
And then put your swipe gesture for specific view controller.
Follow steps below to stop swipe gesture for left menu:
1) Go to AMSlideMenuMainViewController.m class, in that select - (void)setup method.
2) Comment following lines from this method will stop swipe gesture.
self.panGesture = [[UIPanGestureRecognizer alloc] init];
[self.panGesture addTarget:self action:#selector(handlePanGesture:)];
[self.currentActiveNVC.view addGestureRecognizer:self.panGesture];
3) After commenting these lines create a swipe gesture in your ViewController and handle your custom logic.

Gesture Swipe - Storyboard Segue

Been reading up on Gesture swiping and how to push on or off UIViews depending on the direction. I just to have come to an issue that I haven't been able to work out. I can recognise the touch events i.e. up, down, left, right. However when I try to segue to another screen (within the storyboard) I receive an error that is so vague I'm not sure where to begin. I have seen other apps do this so clearly it can be done, just have not found the correct tut or example. Below is the code if anyone had an idea.
- (void)viewDidLoad
{
UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(didSwipe:)];
swipeUp.numberOfTouchesRequired = 1;
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:swipeUp];
UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(didSwipe:)];
swipeDown.numberOfTouchesRequired = 1;
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipeDown];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(didSwipe:)];
swipeLeft.numberOfTouchesRequired = 1;
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(didSwipe:)];
swipeRight.numberOfTouchesRequired = 1;
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRight];
[super viewDidLoad];
// Do any additional setup after loading the view.
// [self.view removeGestureRecognizer:swipeUp];
// [self.view removeGestureRecognizer:swipeDown];
// [self.view removeGestureRecognizer:swipeLeft];
// [self.view removeGestureRecognizer:swipeRight];
}
FirstViewController *fvc;
-(void)didSwipe: (UISwipeGestureRecognizer *) sender
{
UISwipeGestureRecognizerDirection direction = sender.direction;
switch (direction)
{
case UISwipeGestureRecognizerDirectionRight:
NSLog(#"you swiped the screen right");
[self performSelector:#selector(goRight:)];
break;
case UISwipeGestureRecognizerDirectionLeft:
NSLog(#"you swiped the screen left");
[self performSelector:#selector(goLeft:)];
break;
case UISwipeGestureRecognizerDirectionDown:
NSLog(#"you swiped down");
//[self performSelector:#selector(goDown:)];
break;
case UISwipeGestureRecognizerDirectionUp:
NSLog(#"you swiped Up");
//[self performSelector:#selector(goUp:)];
break;
default:
break;
}
}
-(void)goRight:(id)sender
{
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"ip5" bundle:[NSBundle mainBundle]];
UIViewController* controller = [storyboard instantiateViewControllerWithIdentifier:#"FirstView"];
controller.transitioningDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}

How to have multiple UIWebviews, each with its own UITapGestureRecognizer?

I have a view controller with 3 UIWebViews, all with the same frame overlaying each other. I use three buttons to switch between them (similar to a segment control). I want to attach a tap gesture recognizer to the webview so that tapping each webview leads to a new controller. However, only the UITapGestureRecognizer for the first webview fires. Can anyone tell me how to get the other two gesture recognizers to fire? This is my code:
- (IBAction)changeWebView:(id)sender
{
UIButton *button = (UIButton *)sender;
switch (button.tag) {
case 0:
{
[self.view bringSubviewToFront:WebView1];
for (UITapGestureRecognizer *recognizer in WebView2.gestureRecognizers) {
[WebView2 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView3.gestureRecognizers) {
[WebView3 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen1)];
tapGestureRecognizer.delegate = self;
[WebView1 addGestureRecognizer:tapGestureRecognizer];
}
break;
case 1:
{
[self.view bringSubviewToFront:WebView2];
for (UITapGestureRecognizer *recognizer in WebView1.gestureRecognizers) {
[WebView1 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView3.gestureRecognizers) {
[WebView3 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen2)];
tapGestureRecognizer.delegate = self;
[WebView2 addGestureRecognizer:tapGestureRecognizer];
}
break;
case 2:
{
[self.view bringSubviewToFront:WebView3];
for (UITapGestureRecognizer *recognizer in WebView1.gestureRecognizers) {
[WebView1 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView2.gestureRecognizers) {
[WebView2 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen3)];
tapGestureRecognizer.delegate = self;
[WebView3 addGestureRecognizer:tapGestureRecognizer];
}
break;
default:
break;
}
}
This sounds like a design issue. Why don't you only have one one UIView and render the correct content depending on what button was pressed. You can then have only one gesture recognizer that will load the proper controller (or perform the correct segue) also depending on the button.
Add UITapGestureRecognizer to a a view and add all 3 UIWebview as a subview on them.Than whenever you detect UITapGestureRecognizer to be tapped get the tag from segmentedController or button whatever you are using and find which one was tapped.
Don't add UITapGestureRecognizer and remove it again and again.

Resources