UIPanGestureRecognizer with UIScrollView - ios

I've been fighting with UIScrollView for a while now.
I have a scroll view which has multiple 'card' style views in it. I want the cards to move vertically, as in swiping up and down.
Imagine MobileSafari's tab view, but with swipe down to close tabs.
I can't figure out how to do this without it conflicting with the scroll view horizontal panning. I either get them both panning, or only one panning (vertical / horizontal).
What's the best practice to make this work perfectly, as in "if you're swiping vertically, stop horizontal swiping, and if you're swiping horizontally, stop vertical swiping".
Thank you!
Here's an illustration of what I want :

The scroll view has its own gesture recognizer: see its panGestureRecognizer property. If you add your own recognizer for detecting the vertical swipe, you can use requireGestureRecognizerToFail: or delegate methods to manage dependencies between the two recognizers.

I'm really confused by the intended behaviour of your app here. You are using swipe and panning interchangeably but they are different gesture recognizers.
Well one way to differentiate is to compare the x and y values of the translationInView: method of the gesture. If y > x, you have a vertical swipe/pan; x > y and you have a horizontal swipe/pan.
Make that gesture recognizer fail if the swipe/pan detected is not the type you are looking out for.

Related

Is there a way to conform UIScrollView to custom swipes without changing to 2-finger swipes

I have scroll view with both horizontal and vertical scrolls (PDF View).
So I wanted to add diagonal swipe to that and figured out that after this:
scrollView?.panGestureRecognizer.require(toFail: swipe)
swipe works, but whole scroll view started reacting only to 2-finger gestures.
So it would be perfect for me to find a solution to remove this conflict of swipes.

Change the scrolling recognition to be more vertically strict?

My application consists of multiple pages by scrolling horizontally - done by having 2 swipe gesture recognizers over the whole ViewController. On every page I have a ViewTable with items that scroll vertically.
Unless I do a perfect horizontal swipe, the TableView takes over the recognition and does a slight vertical scroll on the table rows.
How do it change the scrolling recognition angle for TableView? Because the table's vertical scrolling is responding from touches around 10º ~ 170º. Whereas I'd like them to be 45º for each direction. How do I narrow that angle? So that my main left/right pages respond easier without having to try to do a perfect horizontal swipe.
I have not really made such a gesture but this is how I think this can be achieved. This is similar to ViewPager on Android. You can use a normal Gesture Recognizer over UITableView, calculate how much x and y displacements are there and then decide whether you want to handle the horizontal scroll yourself by shifting the page or pass the control down to UITableView.
But if you keep your Gesture Recognizer below UITableView, you will never get the control to act upon the gesture unless UITableView passes down to you.

UIScrollView - scroll or swipe?

In my app I have a UIScrollView and I need to swipe left and right from one picture to the next, but I also need to recognize a scroll.
How do I differentiate between a scroll and a swipe with UIScrollView?
I believe you're actually looking for is an implementation of UIScrollView with Paging, as you do not need to handle the touch events yourself, or determine if they are scrolls or swipes.
The Apple Documentation on Scroll Views and Paging Mode should help you get started
Look into the UIScrollView Delegate Methods. ScrollView can detect different types of actions drag etc or add swipeGesture directly to the scroll view
StackOverflow has questions already on this
iOS: UIScrollView detecting Swipe Gesture
Setting up UIScrollView to swipe between 3 view controllers
How to recognize swipe gesture in UIScrollView

Pass touches from a UIView to UIScrollView beneath it

I have a UIScrollView stretching over the entire screen, which the user is able to scroll vertically only. Right 'above' it is a UIView with a few buttons, which covers the bottom 120 px only. The user may tap the buttons to invoke their selectors. But I wish to be able to pass the panning movement to the scrollView, so that the user may scroll the scrollView if they pan with a velocity greater than a certain threshold, if the panning begins over the UIView.
How would I go about it?
Thanks
You can do 2 things.
Add a UITouchesMoved function to your uiView, calculate finger movement and move your scrollView accordingly by scrolling it to a CGPoint.
You can use UIPanGestureRecognizer.

Disable scroll in UIScrollView while multi touching

In my program I use two fingers to pinch (zoom in and out), so sometimes when I want to pinch, app scrolls.
I would like to don't let scrolling in UIScrollView while two or more touches are on screen. How can I achieve that?
Try using UIGestureRecognizer.
In you case you must use a UITapGestureRecognizer, with 2 finger and one tap.
Attach the gesture on the table view.

Resources