I've got a view on the bottom of my ViewController ( similar to Google Maps Bottom Sheet ). The goal is:
When panning up, the view moves towards the pan direction ( essentially follows the finger), when panning ends, the view goes fullscreen. So far so good, all works.
Adding swipe gestures. When swiping up, the view should go full screen.
The issue is that by definition, a swiping gesture is a pan gesture but not the other way around. So unless i go really slow with my panning , the swipe gesture will trigger and the view will go full screen even though im still dragging on the screen.
Simply panning up doesnt look much like the kind of swipe im looking for. The swipe gesture im describing should only trigger if the user "flicked" the view momentarily. If they keep on panning the pan gesture should take precedence.
Any ideas how to achieve this? For reference you could check tap on a pin on google maps on either android or ios.
Its a little hard to describe without showing so if it helps im very open to clarify things.
UPDATES
I think the distinction for a swipe that would override the pan as im describing is that it a) took a short amount of time to complete b)the gesture ended with the user lifting the finger off the screen c) (maybe wrong ) the area traversed should not be too big. Sounds a lot like a flick to me..
If you cannot describe the difference between the two gestures in clearly defined terms then it will be difficult to tell the UIGestureRecognizer how to do so. In addition, it is possible that your user will have difficulty figuring out how to properly interact with the screen if your gestures are too similar or complex.
That being said, you may be able to distinguish between a "swipe" and a "pan" by checking the gesture's velocity. You should be able to play around with the UIGestureRecognizerDelegate methods and achieve the effect you want.
Ok i've achieved what was needed. The short answer is that i was looking for a "flick" gesture instead of a pan gesture. Generally its a nono to add custom gestures but as im replicating the google maps bottom sheet component for ios, it would appear that a custom gesture is the only way.
Using Navillus's comment, I added a velocity and gesture end check in the pan recogniser. The result looked like this:
if(recognizer.state == .ended){
if(recognizer.velocity(in: self).y > CGFloat(500) ){
self.pullUpViewSetMode_SUMMARY()
return;
}
if(recognizer.velocity(in: self).y < CGFloat(-500) ){
self.pullUpViewSetMode_FULL()
return;
}
}
//the rest of the pan handling code, namely translating the view up and up follows here
Hope this helps somebody.
Related
I read through a few similar questions here, but most of them are for much older versions of Swift.
This tutorial shows how to create a gesture recognizer and works pretty well: https://www.ioscreator.com/tutorials/swipe-gesture-ios-tutorial-ios11
What I'd like to accomplish is to add functionality that would allow the user to swipe up or down after pressing a button, while still holding the button, and have my app react to the combination of the specific button being pressed and the upward or downward swipe gesture.
Here's the specific design I'm trying to implement. Basically I'd like the user to press the "A" button and then swipe up or down to get the "#" or "b".
Is this possible? The # & b could be image views or buttons (though if they're buttons, I don't want them to be pressable on their own). If this is a crazy design, I welcome suggestions for improvement.
You want to use a UILongPressGestureRecognizer (probably in conjunction with image views). It has the advantage that first it recognizes a finger held down in one spot (the "A") and then it tracks the movement of that finger (panning up to the sharp or down to the flat). Where the finger is held down — i.e., is it in the "A" or not — will determine whether to recognize in the first place. Then if you do recognize, you watch where the finger goes and decide whether it has entered the sharp or the flat.
I ended up using a Pan Gesture Recognizer, and it worked out really well! I am simply using the y coordinate of the pan gesture to determine if the user is moving his/her finger up to the sharp or down to the flat.
I have a set of objects in a UIScrollView that I am able to do the pan gesture. However, I would like to be able to scroll the view if i'm doing a swipe even if i hold the object and swipe too fast. Is it possible for me to calculate the speed of the drag and drop so i can make the UIScrollView move instead of executing a drag and drop of the swipe is fast?
What would be the solution for this? Please advise
There may be a simpler way. You can ask a gesture recognizer to wait for another to fail before starting. It seems to me that it is what you want to achieve. Can you try :
[scrollView.panGestureRecognizer requireGestureRecognizerToFail:myGestureRecognizer];
or the other way
[myGestureRecognizer requireGestureRecognizerToFail:scrollView.panGestureRecognizer];
In my iPad project i have to make
1.Tap gesture
2.Swipe right and Swipe left Gesture
3.Single Finger Pan Gesture
4.Two finger Pan gesture.
5.Long press gesture
I don't know how to handle all these gestures.When Long press gesture is used only Swipe right gesture and two finger Pan gesture has to work. App gets confused at these many gestures in a single screen. How to Handle everything easily. Please help
Firstly i will say your question was little confusing and we can easily add multiple UITapGestures on a singleView without any prob. The OS automatically detects which gestures you are doing. There are many tutorials for that. Look at these links, if you still can find any solution, tell me may be i can try a code piece for u.
Link 1
Link 2
and lastly
Link 3
I'm new to developing iOS apps,
I've successfully implemented a Swipe Gesture Recognizer,
What I was wondering is if there is an easy to use recognizer like the swipe gesture. That would let you implement the homescreen page turning effect but just on a small view in the view controller?
If your unclear on what effect I mean, when you look at the iPhone's homescreen you can drag your finger and it responds instantly (unlike swipe) and also has some spring feeling to it, is this some effect I can use, or do I manually have to program this into the code if so is there a tutorial that explains this?
Thanks,
I hope my question makes sense.
Have a look at UIPanGestureRecognizer:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIPanGestureRecognizer_Class/Reference/Reference.html
UIPanGestureRecognizer is a concrete subclass of UIGestureRecognizer
that looks for panning (dragging) gestures. The user must be pressing
one or more fingers on a view while they pan it. Clients implementing
the action method for this gesture recognizer can ask it for the
current translation and velocity of the gesture.
A panning gesture is continuous. It begins
(UIGestureRecognizerStateBegan) when the minimum number of fingers
allowed (minimumNumberOfTouches) has moved enough to be considered a
pan. It changes (UIGestureRecognizerStateChanged) when a finger moves
while at least the minimum number of fingers are pressed down. It ends
(UIGestureRecognizerStateEnded) when all fingers are lifted.
Clients of this class can, in their action methods, query the
UIPanGestureRecognizer object for the current translation of the
gesture (translationInView:) and the velocity of the translation
(velocityInView:). They can specify the view whose coordinate system
should be used for the translation and velocity values. Clients may
also reset the translation to a desired value.
Edit: The spring feeling part you would need to implement yourself. Since iOS 7 there is UIDynamics which contains different animators, for what you describe you may need UIGravityBehavior and maybe UICollisionBehaviour. Look at the WWDC 2013 videos for this topic, I think you will find some examples there.
I know this has been probably asked before but I've seen many approaches and i don't know which is best for me, so plz don't send me a link to another post unless it addresses my problem directly.
I have a controller which has a uiview on the top (like a header) (this header is bigger than it seems because is partially hidden on top). on that view i have a uibutton which now with a touch up inside shows the entire header view and taping again returns it to its starting position (changing frame with animation). I want to also be able to drag the view but only changing position on the y axis(dragging up and down)... i was thinking of adding the dragInside/Outside event to the button but this doesn't give me the position of the finger... and also want to know when the user releases the drag so the view ends animation to any of its two possible states (showing or partially hidden). Is this a "touches began" , "touches moved" , "touches ended" thing? if it is please provide a code example. I also want to do this with another view but this is on the left side... same thing but this one moves on the X axis... any help is appreciated. or maybe it can be made with drag event if i only can save a CGpoint of last touch, maybe that's better, any other suggestions
Look at using a UIPanGestureRecognizer to detect the touch movements. Use the translationInView: of the gesture to set the view y position. The translation is the total movement since the start of the gesture so you don't need to remember and accumulate the offset position yourself.
The main thing to worry about while implementing this is bounding the y position of the view so that no matter how far the user drags the view won't go too high or low on the screen.
Use a UIPanGestureRecognizer, that's a class dedicated to handling such drag/pan gestures.
Everything is described here in Apple's documentation, including examples, so you should find your answer here.
There is also some sample code in Apple Developer Library that shows you how to use Gesture Recognizers if needed.