I have a UIView at the bottom of my screen with a UIButtonon top, showing, when I press the button, view slides up with a nice animation.
Everything works fine, now I would like to enable swipe up gesture in the UIButton, so user doesn't actually have to press the button but just slide the finger.
To slide up the view, I just set the frame of it in button action. Now, would be also nice to swipe the view with the finger, something like when you release the view goes up or down, but if you don't release the swipe, the view stays at your finger. Does that make sense?
How could I achieve this?
[UIView animateWithDuration:1.0 animations:^{
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
self.sliding.view.frame = CGRectMake(0, 418, 320, 150);
}];
Do you want to swipe the view, or swipe the button?
In either case, what you would do would be to create and configure a UISwipeGestureRecognizer, and attach it to the field that you want to respond to the swipe gesture.
I would suggest attaching the gesture recognizer to the view that's being moved, not to the button. I think it would be confusing to swipe on a button and have it slide a view to the side as a result.
Take a look at the docs on UISwipeGestureRecognizer in Xcode. You'll want to set the direction and number of touches required.
You'll want to create a swipe gesture recognizer with initWithTarget:action:, then attach it to the view with the UIView method addGestureRecognizer:. If you are attaching the gesture recognizer to a non-control, you might need to set the userInteractionEnabled flag on the view to YES.
In order to achieve this, you need to use swipe gesture recognizers.
UISwipeGestureRecognizer object is will help you to swipe movement with your fingers in any way.
It's include left and right direction due to understand the user which way to swipe .
Related
Ok, here is the thing:
I need to have few animations happening on every screen change in my PageViewController.
So, when a user swipes, an image should fly in from the top left corner, from example.
I can make that animation to happen over time when user swipes and changes the page, but what I need is to that animation to be synchronised with the swipe movement itself.
So if a user presses the screen and starts swiping, the animation should follow user's finger and animate it's translation with the finger movement.
How can I achieve that?
I guess I need some sort of swipe gesture listener, but I failed to find any solution online. I guess I'm not using the right keywords.
You can use a UIPanGestureRecognizer to get the number of pixels swiped:
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panRecognizer_Panned:)];
[self.myViewToSwipe addGestureRecognizer:panRecognizer];
...
- (void) panRecognizer_Panned:(UIPanGestureRecognizer *)recognizer {
CGFloat pixelsMovedHoriz = [recognizer translationInView:self.vwRelativeTo].x;
}
I have two UIButtons in a view (one is YES, the other NO). I now want to add a "did not answer", which would be indicated by a downward swipe on the view.
The problem is that the user may swipe down on the view, but in the process hit one of the buttons. When this happens I want to ignore the button press if there was a swipe underway. If it is just a tap on a button, the answer is recorded.
So, if the swipe occurs, I want to call the swipe gesture's action method. If it is determined no swipe occurred but one of the two buttons was touched I want to call their respective action methods. But if a button was touched in the process of a swipe, I want to call only the swipe gesture's action method.
I know there is a way but I'm wondering whether there is an EASY way of doing this. TIA for suggestions.
Since UISwipeGestureRecognizer is a "discrete" gesture, it just triggers a single action when recognized and it won't allow you to detect the end of the gesture.
So to prevent other touches during the gesture, I'd recommend using a UIPanGestureRecognizer instead since it can track your gesture from beginning to end. Then you can try setting your gesture's cancelsTouchesInView property to YES to cancel all other touches in the view that happen while that pan gesture is recognized, ex:
gesture.cancelsTouchesInView = YES;
gesture.delaysTouchesBegan = YES;
Your buttons should be registering touch up in view, so that someone who taps on the button can drag off if they decide not to proceed.
For your other swipe gesture, your buttons will not register a touch up in view during a swipe gesture, even if the swipe passes over the button or ends on it.
Okay, this seems to work. On the gesture recognizer, I used:
UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeDown:)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
swipeDown.delaysTouchesBegan = YES;
swipeDown.delegate = self;
[self addGestureRecognizer:swipeDown];
They delaysTouchesBegan = YES allows it to determine whether the swipe has occurred before passing the touches on to the buttons. So, if you swipe, it calls the swipe GR, and if you touch either button, you get that. Thanks for your answers...
I need UI like this:
with 2 buttons (yellow and red) and background view (grey), which will have next behaviour:
- highlight button when i press on it;
- execute when i release on button;
- when i press and move in on button from any other view, button became highlighted (ex: press on grey rect and release on red, or press on yellow and release on red);
- support gestures for buttons (like long press and swipe)
So for solving my problem i found only next way:
I redefine for my GrayView touch methods: touchesCancelled, touchesMoved, touchesBegan, and there are i check if current touch position is belong to some rect - i execute appropriate action. But for this solution i have to make my buttons with userInteractionEnabled = false, which means they doesn't support gestures or other events anymore. So if i what to use support it, i have to implement it by myself, what i don't what to do.
So how can i solve this?
If i understand correctly, you can add the gesture recognizers to the gray view as well. And when the gesture recognizer fires find which colored view was in the touch area:
- (void)tapAction:(UITapGestureRecognizer*)recognizer{
if(recognizer.state == UIGestureRecognizerStateEnded){
CGPoint position = [recognizer locationInView:grayView];
if(CGRectContainsPoint(redView.frame, position) {
...
}
}
}
I have a view controller that consists of three views (self.panedview, self.view, self.sineview) When a swipe up gesture is detected, the highest view (self.panedview) is moved up halfway - revealing two additional views (self.view and self.sineview). self.sineview is a UIView that constantly has an animation running that renders a moving sinewave and takes up half of self.view. I have a swipe down gesture recognizer that works when I swipe down on self.panedview, but doesn't work when I swipe down on self.sineview. If I swipe around self.sineview on self.view it seems to work. When I hide self.sineview and swipe directly down on either self.view or self.paned view, the swipe down works. do you think the animating sine wave gets in the way of the gesture recognition.
UISwipeGestureRecognizer * swipeDownRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleDownSwipe:)];
[self.panedView addGestureRecognizer:swipeDownRec];
[self.view addGestureRecognizer:swipeDownRec];
[self.sineview addGestureRecognizer:swipeDownRec];
Also I tried varying between these two lines of code but there is no difference:
[self.view insertSubview:self.sineWave belowSubview:self.panedView];
[self.view insertSubview:self.sineWave aboveSubview:self.view];
I also tried adding a separate swipe down gesture recognizer for each view, but it still doesn't work.
The problem was the that the swipe recognizer for self.sinewave couldn't be recognized while the self.sinewave animation was enabled. The solution is simple: add UIViewAnimationOptionAllowUserInteraction as a parameter to the options handler for animateWithDuration:delay:options:animations:completion:
I have written a UIScrollView subclass that I am using to scroll a series of UITableViews. See the following diagram:
As you can see I have several vertically scrolling UITableViews, that are being scrolled horizontally inside a parent UIScrollView. This all works fine. However the application has a number of global gestures. For example, if I swipe in a given direction with 2 fingers, I do a UIView transition to another part of the app. but if I do the gesture on top of the scroll view and/or its child table views, they naturally scroll their content. This doesn't look good and causes some layout issues.
What I would like to figure out is how to disable all scrolling, on both the UIScrollView and its child UITableViews, when a user touches anywhere with two fingers, and only with two fingers. I've tried variations of overriding touchesBegan, touchesEnded, touchesShouldCancel etc... but I can't get it quite right. Any help is much appreciated.
Here is my gesture handling code:
UISwipeGestureRecognizer *twoFingerSwipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerSwipe:)];
[twoFingerSwipeUp setNumberOfTouchesRequired:2];
[twoFingerSwipeUp setDirection:UISwipeGestureRecognizerDirectionUp];
[twoFingerSwipeUp setDelegate:self];
// 'self' is the superview of the UIScrollView, which is a UIView.
[self addGestureRecognizer:twoFingerSwipeUp];
[twoFingerSwipeUp release];
// ... repeat the above code for up, down, left, right gestures ...
- (void)handleTwoFingerSwipe:(UISwipeGestureRecognizer*)swipeGesture {
switch ([swipeGesture direction]) {
case UISwipeGestureRecognizerDirectionUp:
[self changeToView:viewAbove];
break;
case UISwipeGestureRecognizerDirectionDown:
[self changeToView:viewBelow];
break;
case UISwipeGestureRecognizerDirectionRight:
[self changeToView:viewToTheRight];
break;
case UISwipeGestureRecognizerDirectionLeft:
[self changeToView:viewToTheLeft];
break;
}
}
Try setting panGestureRecognizer.maximumNumberOfTouches = 1 on all scroll and table views (iOS 5 only).
If you're using a swipe recogniser for the two-finger swipe, require the recognisers of the scroll view (including the table views — they're scroll view as well) to fail when the two-finger recogniser recognises its gesture.
[[scrollView panGestureRecognizer] requireGestureRecognizerToFail: twoFingerRecogniser];
Iterate the above code for every scroll view and table view.
(P.S.: "recogniser" is British English, not a spelling err.)
Hope that helps. :-)
Write this code:
scrollView.minimumZoomScale=1.0;scrollView.maximumZoomScale=1.0;
scrollView.delegate self];
And Here is scrollViewDelegate Method:-
-(UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView{
return aScrollView;}
One thing that you should be doing is to check that the gesture has finished before acting upon it:
if (swipeGesture.state == UIGestureRecognizerStateEnded) {
// Do your think
}
I've known odd things to happen otherwise.
Just disable user interaction in the parent scroll view. You need a UIWindow subclass and override -sendEvent: method because this gets called BEFORE any gesture recognizer. There, if you detect two touches, send a notification. Let the scroll view listen to it and disable user interaction if it occurs. And if touches ended, let it re-enable user interaction.