Can I make a UIPresentationController userInteractionEnabled on a PresentingViewController?

I am creating a graphical user interface for a universal application for iPhone and iPad. On the iPad, it relies heavily on "sideViews" for utilities such as content manipulation, detailInformation, etc. (Think of an advanced SplitView). From a visual point of view, the new UIPresentationController is designed to allow me to introduce these β€œsideViews” (and not use dimmedView), and the implementation was easy to build and maintain, but it goes well with the storyboard. But I need to be able to manipulate the contents of an existing ViewController while the presented ViewController is visible. So my question is: can I set userInteractionEnabled (or similar) in the ViewController in the sideViews?

+8
ios ios8 uipresentationcontroller
source share
3 answers

UIPresentationController inserts its container view as a window subzone above the presentation view, so any touches outside the presentation view are trapped in the container view and never fall into the presentation view.

The fix is ​​to insert the view into the container view, which goes through touches on the view view. You can use this as a dimming view or set its backgroundColor to [UIColor clearColor] for a fully transparent view. Set the view representations in your presentation controller code.

 @interface IVPasserView : UIView @property (strong, nonatomic) NSArray* passthroughViews; @end @implementation IVPasserView - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView* hit = [super hitTest:point withEvent:event]; if (hit == self) for (UIView* passthroughView in _passthroughViews) { hit = [passthroughView hitTest:[self convertPoint:point toView:passthroughView] withEvent:event]; if (hit) break; } return hit; } @end 

Note: while this breaks the spirit -[UIView hitTest:withEvent:] , since it does not return a subview, this is actually the way the UIPopoverPresentationController system standard UIPopoverPresentationController . If you set the passthroughViews property there, the container view responds to hitTest:withEvent: with the proxy view, although they are not a superview / subview! Thus, he is likely to survive in the next release of iOS.

+11
source share

Ok, so it seems like the idea of ​​a UIPresentationController CANNOT use it as an extended SplitView (or at least my current output). However, I managed to create a workaround. If someone finds a better way to handle this, please let me know in the comments.

So what I do, I insert the PresentingViewController in the transitionContexts containerView container (same as the UIPresentationControllers containerView) in Index 0. This allows me to transparently handle touchEvents in the PresentingViewControllers. But it removes the PresentingViewControllers view from its original view hierarchy, so I need to move it there when the presentation is fired. This means that the presentation of the view is back to the parentViewController, if present, or to the application window, if presentingViewController is the root controller of the application (there may be other scripts, but this will be done now).

This is all done in animateTransition in UIViewControllerAnimatedTransitioning.

Here's the code snippet:

 UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.5, options: UIViewAnimationOptions.BeginFromCurrentState|UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in animatingView.frame = finalFrame }) { (finished:Bool) -> Void in if !self.isPresentation { if let parentViewController = backgroundVC.parentViewController { parentViewController.view.addSubview(backgroundVC.view) } else if let window = (UIApplication.sharedApplication().delegate as! AppDelegate).window { window.addSubview(backgroundVC.view) } fromView.removeFromSuperview() } else { containerView.insertSubview(backgroundVC.view, atIndex: 0) } transitionContext.completeTransition(true) } 
+2
source share

The modal presentation is not suitable for your situation. It’s best to implement your script with a custom container view controller and override the showDetailViewController:sender: method to handle the views of additional view controllers. You can adapt this method to show the display controller modal on the iPhone and on the right on the iPad, for example.

Here is an excerpt from the Apple Documentation :

View versus view controller view

The UIViewController class offers two ways to display the Controller view:

showViewController: sender: and showDetailViewController: sender: methods offer the most adaptive and flexible way to display view controllers. These methods allow the view controller to decide how best to handle the presentation. For example, a container view of a controller may include a view controller as a child, instead of representing it modally. The default behavior is a view of the controller. CurrentViewController: animated: completion: the method always displays the view controller. The kind of controller that invokes this method may not, but the presentation is always modal. This method adapts the presentation style for horizontally compact environments. showViewController: sender: and showDetailViewController: sender: methods are the preferred way to trigger presentations. The view controller can call them without knowing anything about the rest of the hierarchy of the view manager or the controllers of the current view of the position in this hierarchy. These methods also facilitate the reuse of browse controllers in different parts of the application without written permission of the conditional code paths.

+1
source share

All Articles