Disable gesture to pull down form/page sheet modal presentation

前端 未结 14 2748
我寻月下人不归
我寻月下人不归 2020-11-27 13:58

In iOS 13 modal presentations using the form and page sheet style can be dismissed with a pan down gesture. This is problematic in one of my form sheets because the user dra

相关标签:
14条回答
  • 2020-11-27 14:12

    In the presented ViewController use this in viewDidLoad:

    if #available(iOS 13.0, *) {
        self.isModalInPresentation = true
    }
    
    0 讨论(0)
  • 2020-11-27 14:15

    You can use the UIAdaptivePresentationControllerDelegate method presentationControllerDidAttemptToDismiss and disable the gestureRecognizer on the presentedView. Something like this:

    func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {      
        presentationController.presentedView?.gestureRecognizers?.first?.isEnabled = false
    }
    
    0 讨论(0)
  • 2020-11-27 14:19

    you can change the presentation style, if its in full screen the pull down to dismiss would be disabled

    navigationCont.modalPresentationStyle = .fullScreen
    
    0 讨论(0)
  • 2020-11-27 14:19

    For navigation Controller, to avoid swipe interaction for presented view we can use:

    if #available(iOS 13.0, *) {navController.isModalInPresentation = true}
    
    0 讨论(0)
  • 2020-11-27 14:20

    Will try to describe method 2 already suggested by @Jordan H in more details:

    1) To be able to catch and make decisions about the modal sheet's pan gesture add this into view controller's viewDidLoad:

    navigationController?.presentationController?.presentedView?.gestureRecognizers?.forEach {
       $0.delegate = self
    }
    

    2) Enable the ability to catch the pan gesture together with your own gestures using gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)

    3) The actual decision can go in gestureRecognizer(_:shouldBeRequiredToFailBy:)

    Example code, which makes the swipe gesture to be preferred over sheet's pan gesture, if both present. It doesn't affect original pan gesture in areas where there is no swipe gesture recognizer and therefore the original "swipe to dismiss" can still work as designed.

    extension PeopleViewController: UIGestureRecognizerDelegate {
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            if gestureRecognizer === UIPanGestureRecognizer.self && otherGestureRecognizer === UISwipeGestureRecognizer.self {
                return true
            }
            return false
        }
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }
    

    In my case I have only a few swipe gesture recognizers, so comparing types is enough for me, but if there more of them it might make sense to compare the gestureRecognizers themselves (either programmatically added ones or as outlets from interface builder) as described in this doc: https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/preferring_one_gesture_over_another

    Here's how the code works in my case. Without it the swipe gesture was mostly ignored and worked only occasionally.

    0 讨论(0)
  • 2020-11-27 14:23

    Me, I use this :

    -(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    for(UIGestureRecognizer *gr in self.presentationController.presentedView.gestureRecognizers) {
        if (@available(iOS 11.0, *)) {
            if([gr.name isEqualToString:@"_UISheetInteractionBackgroundDismissRecognizer"]) {
                gr.enabled = false;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题