Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make a UIPresentationController have userInteractionEnabled on PresentingViewController?

I am building a custom GUI on a universal app for iPhone and iPad. On iPad it relies heavily on "sideViews" for utilities like content manipulation, detailInformation and the like (think of an advanced SplitView). From a visual point of view the new UIPresentationController is spot on for letting me present these "sideViews" (and not using a dimmedView) and the implementation has been simple to build and maintain, while still integrate nicely with the storyboard. But I need to be able to manipulate the content of the presentingViewController while the presentedViewController is visible. So my question is, can I set userInteractionEnabled (or similar) on the presentingViewController while presenting the sideViews?

like image 504
jollyCocoa Avatar asked Feb 13 '15 13:02

jollyCocoa


2 Answers

UIPresentationController inserts its container view as a window subview above the presenting view, thus any touches outside the presented view get trapped by the container view and never make it to the presenting view.

The fix is to insert a view on the container view that passes through touches to the presenting view. You can use this as a dimming view or set its backgroundColor to [UIColor clearColor] for a fully transparent view. Set the passthrough views 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 violates the spirit of -[UIView hitTest:withEvent:] in that it doesn't return a subview, this is in fact how the system standard UIPopoverPresentationController handles it. If you set the passthroughViews property there, the container view responds to hitTest:withEvent: with a passthrough view, even though they are not superview/subview! Thus it's likely to survive the next iOS release.

like image 82
Glen Low Avatar answered Oct 12 '22 16:10

Glen Low


Modal presentation isn't suited well for your situation. It is better to implement your scenario with custom container view controller and override showDetailViewController:sender: method to handle presentation of additional view controllers. You can adapt this method to show view controller modal on iPhone and on the right on iPad for example.

Here is an excerpt from Apple Documentation:

Presenting Versus Showing a View Controller

The UIViewController class offers two ways to display a view controller:

The showViewController:sender: and showDetailViewController:sender: methods offer the most adaptive and flexible way to display view controllers. These methods let the presenting view controller decide how best to handle the presentation. For example, a container view controller might incorporate the view controller as a child instead of presenting it modally. The default behavior presents the view controller modally. The presentViewController:animated:completion: method always displays the view controller modally. The view controller that calls this method might not ultimately handle the presentation but the presentation is always modal. This method adapts the presentation style for horizontally compact environments. The showViewController:sender: and showDetailViewController:sender: methods are the preferred way to initiate presentations. A view controller can call them without knowing anything about the rest of the view controller hierarchy or the current view controller’s position in that hierarchy. These methods also make it easier to reuse view controllers in different parts of your app without writing conditional code paths.

like image 33
Aliaksandr Bialiauski Avatar answered Oct 12 '22 16:10

Aliaksandr Bialiauski