UISwipeGestureRecognizer without touch down - iphone

How do I recognise a UISwipeGestureRecognizer with UISwipeGestureRecognizerDirectionUp and then directly after that, WITHOUT lifting my finger, recognise a UISwipeGestureRecognizerDirectionDown recogniser?
Basically I want multiple UISwipeGestureRecognizers being recognised without lifting my finger when I change direction.
My code so far...
- (void)viewDidLoad {
UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(screenSwipedUp)];
swipeUp.numberOfTouchesRequired = 1;
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
swipeUp.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:swipeUp];
UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(screenSwipedDown)];
swipeDown.numberOfTouchesRequired = 1;
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:swipeDown];
}
- (void)screenSwipedUp {
NSLog(#"SW-Up");
}
- (void)screenSwipedDown {
NSLog(#"SW-Down");
}

I don't think you can do it with UISwipeGestureRecognizer. You can instead use UIPanGestureRecognizer and implement the action OR create a subclass of UIGestureRecognizer and Override the methods to recognize your special gesture.

Related

detect Swipe gesture in UIWebview

I am new to iPhone developer,
I made epub reader and loaded each page of epub in my webview
What i want to is, when user does right swipe gesture 2nd time then i want to navigate to new page, i do not want to do anything when user does right swipe gesture for first time.
UISwipeGestureRecognizer *swipeRight
Is there any method something like,
if(swipeRight.touch.count > 2)
{
// do this
}
Any help will be appriciated.
Thanks In Advance !
EDIT
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset == 0)
{
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
swipeUp.numberOfTouchesRequired=2;
swipeUp.delegate = (id<UIGestureRecognizerDelegate>)self;
swipeUp.cancelsTouchesInView=YES;
[_webview addGestureRecognizer:swipeUp];
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightAction:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.numberOfTouchesRequired=2;
swipeDown.delegate = (id<UIGestureRecognizerDelegate>)self;
swipeDown.cancelsTouchesInView=YES;
[_webview addGestureRecognizer:swipeDown];
}
You can tell the UIWebView's UIScrollView that its UIPanGestureRecognizer should only fire when your own UISwipeGestureRecognizer has failed.
This is how you do it:
UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGesture:)];
UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGesture:)];
rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:rightSwipeGesture];
[self.view addGestureRecognizer:leftSwipeGesture];
[_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:rightSwipeGesture];
[_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:leftSwipeGesture];
That should do the trick for you.
Just attach UIGestureRecognizer subclass to that view and hold on for calls...
UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(someAction)];
rightSwipeRecognizer.numberOfTouchesRequired = 2;
rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipeRecognizer.cancelsTouchesInView = YES;
[self.webView addGestureRecognizer:rightSwipeRecognizer]; // add in your webviewrightSwipeRecognizer
Try like below it will help you
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightSwipeHandle:)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
rightRecognizer.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:rightRecognizer];
[rightRecognizer release];
I don't think that swipe gestures offer support for the kind of behavior you are aiming at, but you can easily accomplish it by doing the following:
on the first swipe, set a flag and start a timer; for the rest do nothing;
on the second swipe,
a. if the timer has fired (when firing, the timer reset the flag), do as per point 1.
b. is the timer has not fired (the flag is still set), then do you action and cancel the timer.
You might event think of defining a subclass of UISwipeGestureRecognizer to encapsulate all this behavior.

How to detect web view page end is reached in iPhone

I am new to iPhone developer,
I made epub reader and loaded each page of epub in my webview, when i see my application in portrait mode scrolling is not there, bcoz i have used,
webview.scalesPageToFit=TRUE;
But when i see my application in landscape mode page fits properly but it occurs with scrolling, so i want to add swiperight gesture when scrolling end is reached so that user can navigate to a next page, on doing rightswipe.
is there any method which tells webview has completed scrolling ?
_ in short how to detect UIWebView reaching the top or bottom ?_
Thanks In Advance !
EDIT
written in did load:
swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightAction:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
swipeRight.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeRight];
swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
swipeLeft.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeLeft];
and then while loading each page i am checking orientation if it is portrait then adding two more gesture up and down gesture if landscape then removing up and down gesture.
if([UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationPortrait || [UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationPortraitUpsideDown) {
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
swipeUp.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeUp];
swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightAction:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeDown];
counterPort++;
counterLand=0;
}
}
if (counterLand==0) {
if([UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationLandscapeLeft || [UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationLandscapeRight) {
[_webview removeGestureRecognizer:swipeDown];
[swipeDown release];
swipeDown=nil;
[_webview removeGestureRecognizer:swipeUp];
[swipeUp release];
swipeUp=nil;
counterPort=0;
counterLand++;
}
after your suggestion:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset == 0)
{
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
swipeUp.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeUp];
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightAction:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeDown];
}
}
In ios 5.0 and later, you can access the UIWebView's scrollView property. If you set that scrollView's delegate to your object, you can find out when it reaches the top or bottom. Just make sure you hold a reference to the previous scrollview delegate before changing.
_defaultDelegate=[webview.scrollView.delegate retain];
webview.scrollView.delegate=myController;
Your _defaultDelegate declaration will be
id <UIScrollViewDelegate> _defaultDelegate;
Now, in myController's implementation of scrollViewDidScroll:, you can find out if the scrolling has reached the end or beginning of the page.
The tricky thing is that you must implement other UIScrollViewDelegate Methods and pass on to the default delegate so that the webview does not lose its default behaviour. So, you implement like so
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
[_defaultDelegate scrollViewDidScrollToTop:scrollView];
}
Refer to this answer for finding out if scrollView scrolls to top or bottom:
iPhone - knowing if a UIScrollView reached the top or bottom
EDIT: After reading your code, I don't think you should be adding and removing your gesture recognizers like that. Create 4 gesture recognizers which covers all the possible swipe directions and add it to the webview in viewDidLoad. You can control if the gesture recognizer should respond by implementing the method :
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
Don't forget to set the delegate for each gesture recognizer and also checkout the other UIGestureRecognizerDelegate Methods. The view Controller has a property interfaceOrientation that you can access also.
To solve the scrolling issue, try having a BOOL iVar to indicate if you are at the bottom in the code.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
_atBottom=NO;
if (scrollOffset == 0)
{
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftAction:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
swipeUp.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeUp];
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRightAction:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.delegate = (id<UIGestureRecognizerDelegate>)self;
[_webview addGestureRecognizer:swipeDown];
_atBottom=YES;
}
}
and implement the UIGestureRecognizerDelegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return _atBottom;
}

Can UILongPressGestureRecognizer and UISwipeGestureRecognizer be used together?

I have the following code which creates four gestures:
self.userInteractionEnabled = YES;
UIPanGestureRecognizer * panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[panGesture setDelegate:self];
[self addGestureRecognizer:panGesture];
UILongPressGestureRecognizer * longPressGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPress:)];
longPressGesture.minimumPressDuration = 0.00;
[self addGestureRecognizer:longPressGesture];
UISwipeGestureRecognizer * swipeUp = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleSwipeUp:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[self addGestureRecognizer:swipeUp];
UISwipeGestureRecognizer * swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleSwipeDown:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
[self addGestureRecognizer:swipeDown];
The Pan and LongPress work fine, but I never get either of the Swipe gestures. Is there something special I need to do to have the swipe selectors get called?
Thanks
I just answered this yesterday.
Short form: a swipe gesture is a special case of a pan gesture, and by default no two gestures will recognize simultaneously. Look into gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: and/or requireGestureRecognizerToFail:. You'll find further help for this and related issues in Apple's guide.

iPhone simulator swipe right works, but swipe left does not?

I'm trying to use swipe left and right on a UIScrollView. However it looks like swipe left does not work in iPhone simulator even though swipe right does. Did I miss any step?
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.scrollView.multipleTouchEnabled = YES;
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipe.delaysTouchesBegan = YES;
swipe.numberOfTouchesRequired = 2;
[self.scrollView addGestureRecognizer:swipe];
[swipe release];
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer
{
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
} else if (recognizer.direction == UISwipeGestureRecognizerDirectionRight) {
}
}
Use Following:
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightSwipeHandle:)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[rightRecognizer setNumberOfTouchesRequired:1];
[mainSlideShowImageScrollView addGestureRecognizer:rightRecognizer];
[rightRecognizer release];
UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(leftSwipeHandle:)];
leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[leftRecognizer setNumberOfTouchesRequired:1];
[mainSlideShowImageScrollView addGestureRecognizer:leftRecognizer];
[leftRecognizer release];
- (void)rightSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
//Do moving
}
- (void)leftSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
// do moving
}
Your 'handleSwipe' code is actually correct. You need two UISwipeGestureRecognizers but you can point them both to the same handler, containing your 'IF' statement.
You can create one gesture recognizer that handles both left and right swipe (or even all directions-!):
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
All directions:
swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;

GestureRecognizers stop working after using presentModalViewController and dismissing

I am initializing my gesture recognizers with the following code when I initialize a view. However, after multiple times of presenting a view on top of the one with the gesture recognizers and dismissing it with presentModalViewController and dismissModelViewController, the gesture recognizers stop working on the original view. I've tried manually releasing the recognizers in the view's dealloc function rather than using autorelease, but it doesn't seem to help. Does anyone have any ideas? Thanks!
Also, I should mention that this problem only happens on the device, and not the simulator.
-(void) initializeGestures {
recognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)] autorelease];
//recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
[(UITapGestureRecognizer *)recognizer setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
swipeLeftGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureLeft:)] autorelease];
//swipeLeftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureLeft:)];
swipeLeftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeftGesture];
swipeLeftGesture.delegate = self;
swipeRightGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureRight:)] autorelease];
//swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureRight:)];
swipeRightGesture.direction = UISwipeGestureRecognizerDirectionRight; // default
[self.view addGestureRecognizer:swipeRightGesture];
swipeRightGesture.delegate = self;
}
-(IBAction) handleSwipeGestureLeft:(UISwipeGestureRecognizer*)sender
{
[self swipeLeft];
}
-(IBAction) handleSwipeGestureRight:(UISwipeGestureRecognizer*)sender
{
[self swipeRight];
}
-(IBAction) handleTapGesture:(UITapGestureRecognizer *) sender {
[self gotoDefinition];
}
did the view with gesture recognizers dealloc when you present another viewController?
this will cause the view remove gesture recognizers on it