How do I create a view that allows some gestures to "pass-through", basically I have 2 views the top view completely covers the other, I need the top view to handle left/right swipes and the one below has a UIScrollView that needs to respond to up/down swipes, tap and long press, so essentially pass the events down the chain.
Is this the wrong approach?
Related
Suppose there are two UIVIew subclasses in two different regions of the screen.
The first UIView subclass is a table or collectionView
The second view is a simple UIView.
Is it possible for gestures inside the second view to be "carried over" to the first view so that for example, a swipe up gesture in the second view would make the table/collection view scroll up ?
In WWDC 2012 Session 223: Enhancing User Experience with Scroll Views, Apple engineers explained that you can take a scroll view's panGestureRecognizer and add it to a different view to make that other view control the scroll view's scrolling.
Note that UITableView and UICollectionView are subclasses of UIScrollView.
So if you can put your table view and your second view into a common superview, you can move the table view's panGestureRecognizer to the superview and it will detect touches on both subviews.
[commonSuperview addGestureRecognizer:tableView.panGestureRecognizer];
The best way to achieve that is to encapsulate your 2 views in a another view and to add the GestureRecognizer on the motherView.
This way when the gesture triggers, with the location of the touch you can figure out if it started in one view or the other and you can track the move all the way to the second view.
I have a UIScrollView with another view behind it that has buttons. The buttons cannot be on the scroll view, they must be behind it. I am using the pointInside method to pass taps to the buttons view behind the scroll view if that is where the user is tapping. However, I don't want to pass the tap to the buttons view if the user is trying to drag/scroll. If that is the case I want it to scroll the scroll view instead of pass a tap to the buttons.
How can I accomplish this?
UIScrollView has a panGestureRecognizer property. Use the pan gesture's state to determine if you have to pass touches to your button or not.
I have a UIView organized with two columns and each column have it own UIViewController. I need to hide my left view when the right view receive a swipe gesture with the left direction.
I added a UISwipeGestureRecognizer to the right view and the code works when the gestures begins and ends in the right view. However, if my gestures begins in the right view and ends in the left view my event is not triggered.
Anyone know how I can handle this?
I'm building an iOS layout which consists of a UITableView and a UIScrollView. The UIScrollView is inside a table cell of the UITableView and can be scrolled both horizontally and vertically. The diagram below shows this situation. If the user begins scrolling down/up on the UIScrollView the scrolling event should trigger setContentOffset of the table view, and not setContentOffset for the scroll view while the top of the scroll view will be on the dotted line (it's constant height). Then a scrolling touch event should trigger setContentOffset for the scroll view, not for the table view.
In another case: When the user starts scrolling on the table view, it should trigger setContentOffset for the table view, until the scroll view reaches the dotted line. Then the scroll view should handle setContentOffset.
My problem is how to transfer touch events between the table view and the scroll view during one sliding action.
This sounds like one of those cases where you want something quite specific and custom. So trying to do something clever with the gesture recognizers won't be enough.
The main problem is that the ways you can control gesture recognizers such as with gestureRecognizer:shouldReceiveTouch: and gestureRecognizerShouldBegin: only affect the start of the gesture (or for new touches, not ongoing ones), but you want a single ongoing gesture to transition between controlling each view. So for this reason I think you will need to place a large transparent view over your entire screen with a pan gesture recognizer on it and in your handlePan method decide which view you want to adjust and then call setContentOffset directly on that view. You can use the translation of the pan recognizer and the existing content offset to calculate the new one. I know this isn't very elegant, but I can't think of another way to achieve the effect you want.
I'm not sure if this is going to work, but you could try doing something like this:
Option
self.scrollView.panGestureRecognizer = self.tableView.panGestureRecognizer;
Option
[self.scrollView addGestureRecognizer:self.tableView.panGestureRecognizer];
Option
[self.tableView.panGestureRecognizer requireGestureRecognizerToFail:self.scrollView.panGestureRecognizer];
I have a view-chain; the first view is in the second, the second is in the third and so on.
I want to move the top most view under my finger and I did some logics to handle this in touchesBegan:touchesMoved:...
The problem is that each view has different gestures and if I try to move the top most view, the views behind it also respond to the moving. Is there any way to disable the gesture except the top most view when I am trying to move it?
Also I do not want the top most view to go outside the border of its immediate parent view, and I did some logics in the touchesMoved: to reset the center or the top-most view. The effect is not good as this approach allows the view to go outside, but will move it back once it went out.
How about just creating and turning on a disable flag at the bottom views while adding the top most view to it's parent view, if you don't want the bottom views to respond to their own gesture recognisers?