in iOS when I add a childviewcontroller, then remove it - all gestures that overlap have been disabled.
For example the parentviewcontroller has a 'longtap' gesture, and the childviewcontroller has a 'longtap' gesture.
the parent views longtap gesture works.
then i do addchildviewcontroller and that VCs longtap gesture works.
then i call removeFromParentViewController
and the original viewcontroller's view which used to respond to longtap gestures has had its gesture disabled.
(I could cycle through all the gestures and 'renable' them again - my question is why is the longtap gesture getting disabled when i add, and then remove a childviewcontroller - I'm doing everything standard, ie.
[_parentVC addChildViewController:alertVC];
[_parentVC willMoveToParentViewController:alertVC];
[_parentVC.view addSubview:alertVC.view];
then
[alertVC.view removeFromSuperview];
[alertVC removeFromParentViewController];
[alertVC willMoveToParentViewController:_parentVC];
Wow.
A lot of code here.
Looks like the gesture was manually disabled after the event took place. So the gesture being disabled had nothing to do with adding childviewcontrollers.
Related
I am currently facing a scenario that I am using a UIPageViewController on a view & I want the right swipe gesture to work when user swipe right side from index value 0, so I am trying to add a right swipe gesture to UIPageViewController by the following code:
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightSwipeHandle:)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[rightRecognizer setNumberOfTouchesRequired:1];
//Edit 1
[self.pageViewController.view addGestureRecognizer:rightRecognizer];
but, while I am adding gesture to pageviewcontroller I am getting following error message (Solved by #Lyndsey Scott answer)
no visible interface uipageviewcontroller declares the selector addgesturerecognizer
Can anyone guide me that how can I implement the right swipe in this pageViewController
Edit 1: Replaced the code provided by #Lyndsey Scott, removed the error, but problem still exists that I am not able to trigger that swipe event.
You have to the gesture to the UIPageViewController's view:
[self.pageViewController.view addGestureRecognizer:rightRecognizer];
Edit in response to your edit:
The swipe gesture won't work if you haven't implemented any UIGestureRecognizerDelegate methods to allow for the UIPageViewController's swipe gesture and your swipe gesture to be recognized simultaneously. Right now, your swipe is essentially being blocked by the page controller's gesture. You could change that by implementing the UIGestureRecognizerDelegate, setting rightRecognizer.delegate = self;, and overriding gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer such that it returns true in the case that both gesture recognizers are triggered.
But if you want the page to flip and your gesture to be recognized at the time of that page flip, adding the extra swipe gesture is unnecessary since you can simply trigger your method upon page turn; for example in pageViewController:didFinishAnimating:previousViewControllers: transitionCompleted:.
You shouldn't have to add the gesture recognizer, if you implement the protocol correctly it should work out of the box.
The point of UIPageViewController is to not have to do it manually.
I have added a subview to a View Controller's view. This subview is the view of QLPreviewController.
What I am trying to achieve is to recognize swipe gestures on the subview in the parent view, i.e. the View Controller's view. In the end, I want to be able to swipe left /right on the view to load the next document for preview.
I'm aware of hit testing and understand that by just attaching a gesture recognizer to the parent view, those will not be recognized, since the subview will be the "hit-test" view.
Now what is the best (or easiest) way to recognize those gestures?
Note: I didn't manage to attach the gesture recognizers to the subview, this doesn't seem to work.
* UPDATE *
To make this more clear - this is the code from my ViewController. vContent is just a view in my ViewController, where I add the view of the QLPreviewController:
let pvVc = QLPreviewController()
pvVc.dataSource = self
vContent.addSubview(pvVc.view)
I tried adding the swipe recognizers both to the vContent and the pvVc.view. In both cases no event was fired.
let sgrLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action:Selector("handleSwipe:"))
sgrLeft.direction = UISwipeGestureRecognizerDirection.Left
sgrLeft.delegate = self
On some other view the code works fine.
Any hint is appreciated!
Thx
Eau
Well, the responder chain, the unknown animal … ;-)
You can subclass the superview and override -hitTest:forEvent:.
You rarely need to call this method yourself, but you might override it to hide touch events from subviews.
Gesture Recognizers Get the First Opportunity to Recognize a Touch, so even the subview is hitTest view. the gestureRecognizer attached on superView can recognizer touch event.
I'm using a UISplitViewController and one of the detail view controllers contains a view which has a UIPanGestureRecognizer added to it. When I swipe this view in the detail view controller, the gesture is recognized, but the swipe gesture recognizer of the split view controller interferes with it; the master view controller is displayed and the gesture recognizer from the detail controller is ignored.
Implementing and debugging the shouldRecognizeSimultaneouslyWithGestureRecognizer method from the UIGestureRecognizerDelegate shows two UIPanGestureRecognizer objects: one from the detail view controller and the one from the split view controller, so I'm certain they are interfering with each other.
When I set presentsWithGesture = NO on the split view controller, the gesture recognizer inside the detail view controller does work. But that disables the gesture recognizer on the split view controller, so it's not really a solution to the problem.
I've also tried disabling the gesture recognizer on the split view controller, only when I need the other gesture recognizer to work, but it seems that it is not possible to set presentsWithGesture once the split view controller has become visible.
I've also tried to disable the default gesture on the split view controller and adding a custom gesture which I can control, but it didn't work. I tried using the target and action from the split view controller barbutton on the gesture, but it doesn't work. Calling toggleMasterVisible: on the split view controller isn't an option either because it's part of the private api.
Does anyone have any suggestions on how to handle this?
I would suggest that you disable the UISplitViewController pan gesture when you need the other one to work. This should do it:
for (UIGestureRecognizer* recognizer in [splitViewController gestureRecognizers]) {
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
[recognizer setEnabled:NO];
}
}
You probably don't want to search for it each time, so I would store a reference to that gesture recognizer when the view loads, then just disable and enable as appropriate:
on viewDidLoad:
for (UIGestureRecognizer* recognizer in [splitViewController gestureRecognizers]) {
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
[self setSplitViewPanGesture:recognizer];
}
}
later:
[self.splitViewPanGesture setEnabled:NO];
and later:
[self.splitViewPanGesture setEnabled:YES];
I have UIPageViewController that animates programatically. The problem is that the view controllers inside it has UIButtons inside them. When I hold down a button and wait until the UIPageViewController animates, the app crashes with the error:
'Failed to determine navigation direction for scroll'
What I think I need to do is to somehow fake that the user releases the button before the UIPageviewController animates.
However, [self.button sendActionsForControlEvents:UIControlEventTouchCancel]; doesn't seem to do the trick. Neither do UIControlEventTouchUpInside.
Is there a better way do to it or am I using sendActionsForControlEvents wrong?
All sendActionsForControlEvents: does is call any methods you've assigned to the control events passed in for the button. It doesn't call any internal methods to programmatically lift up touches or anything like that.
Right before you programmatically animate your page view controller, try using this method to effectively cancel any touches on the pan gesture recognizer of the page view controller's internal scroll view:
- (void)cancelPanGestureTouchesOfPageViewController:(UIPageViewController *)pageVC
{
// Since UIPageViewController doesn't provide any API to access its scroll view,
// we have to find it ourselves by manually looping through its view's subviews.
for (UIScrollView *scrollView in pageVC.view.subviews) {
if ([scrollView isKindOfClass:[UIScrollView class]]) {
// We've found the scroll view, so use this little trick to
// effectively cancel any touches on its pan gesture recognizer
BOOL enabled = scrollView.panGestureRecognizer.enabled;
scrollView.panGestureRecognizer.enabled = !enabled;
scrollView.panGestureRecognizer.enabled = enabled;
}
}
}
(Note that this is messing with the internal view hierarchy of UIPageViewController, so this method is kind of ugly and may break in the future. I generally don't recommend doing stuff like this, but I think in this instance it should be okay.)
In my app I have this situation:
I have my main viewcontroller where I alloc a "flipwiecontroller" and add its view in this way
self.flipViewController.view.frame = CGRectMake (...);
[self.view addSubview:self.flipViewController.view];
and at this flipViewController I add some gesture (as pangesture, swipegesture and tapgesture for some control that I use on it)
when I press a button in this view I alloc another viewcontroller "paintingviewcontroller" in this way
[self.view addSubview:paintingViewController.view];
in this second view controller I have some buttons and another function, but when I try to do a swipegesture or a tapgesture it recognize the events of my "flipviewcontroller"
I don't understand, if I add a view controller over another viewcontroller, why gesture of flipviewcontroller are active yet?
thnaks
Maybe you are disabling userIntercation on the paintingViewController, then, it's events are sent to his superview.
Also you can use [UIView removeGestureRecognizer:UIGestureRecognizer] to remove gestures.
How did you add the gesture recognizers? They should be added to the view, not the window. Perhaps that's the issue.
In case you have something like this:
[self.view.window addGestureRecognizer:panGestureRecognizer];
You should change it to this:
[self.view addGestureRecognizer:panGestureRecognizer];