649 votes

Présentation de la modale en plein écran sous iOS 13

Dans iOS 13, il y a un nouveau comportement pour le contrôleur de vue modal lorsqu'il est présenté.

Maintenant, il n'y a pas de plein écran par défaut et lorsque j'essaie de glisser vers le bas, l'application rejette automatiquement le contrôleur de vue.

Comment puis-je empêcher ce comportement et revenir à l'ancien vc modal plein écran ?

modal behaviour

Gracias

3voto

amar Points 1665

Vous pouvez facilement le faire Ouvrez votre storyboard en tant que code source et recherchez kind="presentation" Dans toutes les balises de la mer avec kind = présentation, ajoutez un attribut supplémentaire. modalPresentationStyle="fullScreen"

3voto

iOS Points 411

J'y suis parvenu en utilisant la méthode swizzling(Swift 4.2) :

Pour créer une extension UIViewController, procédez comme suit

extension UIViewController {

    @objc private func swizzled_presentstyle(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) {

        if #available(iOS 13.0, *) {
            if viewControllerToPresent.modalPresentationStyle == .automatic || viewControllerToPresent.modalPresentationStyle == .pageSheet {
                viewControllerToPresent.modalPresentationStyle = .fullScreen
            }
        }

        self.swizzled_presentstyle(viewControllerToPresent, animated: animated, completion: completion)
    }

     static func setPresentationStyle_fullScreen() {

        let instance: UIViewController = UIViewController()
        let aClass: AnyClass! = object_getClass(instance)

        let originalSelector = #selector(UIViewController.present(_:animated:completion:))
        let swizzledSelector = #selector(UIViewController.swizzled_presentstyle(_:animated:completion:))

        let originalMethod = class_getInstanceMethod(aClass, originalSelector)
        let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)
        if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
        method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

et dans AppDelegate, dans application:didFinishLaunchingWithOptions : invoquez le code d'agitation en appelant :

UIViewController.setPresentationStyle_fullScreen()

1voto

Govind P N Points 1016

Créer une catégorie pour UIViewController (disons UIViewController+PresentationStyle). Ajoutez-y le code suivant.

 -(UIModalPresentationStyle)modalPresentationStyle{
     return UIModalPresentationStyleFullScreen;
}

0voto

Luca Iaco Points 948

Une autre approche consiste à avoir votre propre composant de base viewcontroller dans votre application, et à mettre en œuvre les initialisateurs désignés et requis avec une configuration de base, quelque chose comme ce qui suit :

class MyBaseViewController: UIViewController {

//MARK: Initialisers

/// Alternative initializer which allows you to set the modal presentation syle
/// - Parameter modalStyle: the presentation style to be used
init(with modalStyle:UIModalPresentationStyle) {
    super.init(nibName: nil, bundle: nil)
    self.setup(modalStyle: modalStyle)
}

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    // default modal presentation style as fullscreen
    self.setup(modalStyle: .fullScreen)
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    // default modal presentation style as fullscreen
    self.setup(modalStyle: .fullScreen)
}

//MARK: Private

/// Setup the view
///
/// - Parameter modalStyle: indicates which modal presentation style to be used
/// - Parameter modalPresentation: default true, it prevent modally presented view to be dismissible with the default swipe gesture
private func setup(modalStyle:UIModalPresentationStyle, modalPresentation:Bool = true){
    if #available(iOS 13, *) {
        self.modalPresentationStyle = modalStyle
        self.isModalInPresentation = modalPresentation
    }
}

NOTE : Si votre contrôleur de vue est contenu dans un contrôleur de navigation qui est effectivement présenté de manière modale, alors le contrôleur de navigation devrait aborder le problème de la même manière (ce qui signifie, avoir votre composant de contrôleur de navigation personnalisé de la même manière .

Testé sur Xcode 11.1 sur iOS 13.1 et iOS 12.4

J'espère que cela vous aidera

-1voto

Master_Tushar Points 84

Les réponses et suggestions ci-dessus sont justes, ci-dessous est une autre version, et une manière efficace en utilisant programmatiquement.

#1 Création d'une extension UIView

#2 Création d'une méthode ()

//#1
extension UIViewController {

//#2
func presentLocal(_ viewControllerToPresent: UIViewController, animated flag: 
Bool, completion: (() -> Void)? = nil) {

//Reusing below 2 lines :-)
viewControllerToPresent.modalPresentationStyle = .overCurrentContext
self.present(viewControllerToPresent, animated: flag, completion: completion)

  }
}

En invoquant comme ci-dessous

let vc = MyViewController()
let nc = UINavigationController(rootViewController: vc)
sourceView.presentLocal(nc, animated: true, completion: nil)

OU

let vc = MyViewController()
sourceView.presentLocal(vc, animated: true, completion: nil)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X