Presentación modal en pantalla completa de iOS 13

466

En iOS 13 hay un nuevo comportamiento para el controlador de vista modal cuando se presenta.

Ahora no es pantalla completa por defecto y cuando trato de deslizarme hacia abajo, la aplicación simplemente cierra el controlador de vista automáticamente.

¿Cómo puedo evitar este comportamiento y volver al antiguo modo de pantalla completa vc?

comportamiento modal

Gracias

pascalbros
fuente

Respuestas:

622

Con iOS 13, como se indicó en el estado de las plataformas de la Unión durante la WWDC 2019, Apple presentó una nueva presentación de tarjeta predeterminada. Para forzar la pantalla completa, debe especificarla explícitamente con:

let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
pascalbros
fuente
81
Yo diría que esto no se mantendrá por mucho tiempo como predeterminado. La fullScreenopción debe ser predeterminada para evitar que se rompan los cambios de la interfaz de usuario.
Jakub Truhlář
17
No contaré con eso. En el pasado, Apple a menudo cambió los valores predeterminados solo para activarse una vez que se vincula con el SDK actual. Con suerte, obtendremos el comportamiento anterior al vincular con versiones anteriores.
DrMickeyLauer
11
Puedo confirmar que las aplicaciones integradas de Xcode-10 que se ejecutan en el simulador de iOS 13 todavía tienen el valor predeterminado de pantalla completa. Como dijo @DrMickeyLauer, construir con Xcode 11 permite que la aplicación adopte el nuevo comportamiento. Use isModalInPresentationpara bloquear el gesto de deslizamiento para que no se descarte. Vea mi publicación de blog para más detalles: medium.com/@hacknicity/…
Geoff Hackworth
55
Recomiendo usar .fullScreen en lugar de .overFullScreen. .fullScreen dispara viewWillAppear y viewDidAppear, .overFullScreen no hace eso
PiterPan
55
Ha pasado el tiempo y el .automaticestilo se ha establecido como el predeterminado, que es (para la mayoría de los controladores de vista) .pageSheetestilo. Sin embargo, algunos controladores de vista del sistema pueden asignarlo a un estilo diferente.
Jakub Truhlář
186

Agrego una información que podría ser útil para alguien. Si tiene algún guión gráfico, para volver al estilo anterior, debe establecer la propiedad kind en Present Modally y la propiedad Presentation en Pantalla completa .

ingrese la descripción de la imagen aquí

Alessandro
fuente
2
¿Hay alguna manera en Interface Builder para configurar isModalInPresentation?
Brad Thomas el
De acuerdo con esto Cambie el valor de Presentación para las vistas ofensivas de nivel más alto.
David
Este es el que funcionó para mí porque tengo performSegue. ¡Gracias querido!
Blasanka
95

Tuve este problema en la vista inicial justo después de la pantalla de inicio. La solución para mí ya que no tenía una segue o lógica definida fue cambiar la presentación de automático a pantalla completa como se muestra aquí:

fix_storyboard_presentation_default_behavior

davidbates
fuente
2
¿Hay alguna manera de hacer esto programáticamente para todas las vistas en lugar de una por una a través del guión gráfico?
The1993
@ The1993 ¿Encontraste alguna alternativa a eso?
Shobhit Puri
1
@ShobhitPuri Eche un vistazo a la primera solución de Omreyh aquí stackoverflow.com/a/58255416/4323101
The1993
1
Wow, esta fue LA respuesta para mis problemas. ¡Gracias por el consejo! Para cualquier otro que también esté investigando esto, esta es la solución para un comportamiento extraño después de volver a abrir la aplicación desde el fondo. En mi aplicación, abrir desde el fondo superpondría mi pantalla de inicio (controlador de vista inicial) como un estilo de presentación de tarjeta y luego cualquier segue de aquí en adelante se desvanecería en lugar de usar mi estilo de segue definido. Estaría bien si cerraba la aplicación (toca dos veces el botón de inicio y deslizo hacia arriba, luego vuelvo a abrir), pero cualquier lanzamiento adicional causaría este comportamiento extraño. ¡Gracias de nuevo!
Justin
92

Hay varias formas de hacerlo, y creo que cada una podría encajar en un proyecto, pero no en otro, así que pensé que las mantendría aquí, tal vez alguien más se encargaría de un caso diferente.

1- Anular presente

Si tiene un BaseViewControllerpuede anular el present(_ viewControllerToPresent: animated flag: completion:)método.

class BaseViewController: UIViewController {

  // ....

  override func present(_ viewControllerToPresent: UIViewController,
                        animated flag: Bool,
                        completion: (() -> Void)? = nil) {
    viewControllerToPresent.modalPresentationStyle = .fullScreen
    super.present(viewControllerToPresent, animated: flag, completion: completion)
  }

  // ....
}

De esta manera, no necesita hacer ningún cambio en ninguna presentllamada, ya que simplemente anulamos el presentmétodo.

2- Una extensión:

extension UIViewController {
  func presentInFullScreen(_ viewController: UIViewController,
                           animated: Bool,
                           completion: (() -> Void)? = nil) {
    viewController.modalPresentationStyle = .fullScreen
    present(viewController, animated: animated, completion: completion)
  }
}

Uso:

presentInFullScreen(viewController, animated: true)

3- Para un controlador UIView

let viewController = UIViewController()
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: true, completion: nil)

4- del guión gráfico

Seleccione una secuencia y establezca la presentación en FullScreen.
ingrese la descripción de la imagen aquí

5- Swizzling

extension UIViewController {

  static func swizzlePresent() {

    let orginalSelector = #selector(present(_: animated: completion:))
    let swizzledSelector = #selector(swizzledPresent)

    guard let orginalMethod = class_getInstanceMethod(self, orginalSelector), let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) else{return}

    let didAddMethod = class_addMethod(self,
                                       orginalSelector,
                                       method_getImplementation(swizzledMethod),
                                       method_getTypeEncoding(swizzledMethod))

    if didAddMethod {
      class_replaceMethod(self,
                          swizzledSelector,
                          method_getImplementation(orginalMethod),
                          method_getTypeEncoding(orginalMethod))
    } else {
      method_exchangeImplementations(orginalMethod, swizzledMethod)
    }

  }

  @objc
  private func swizzledPresent(_ viewControllerToPresent: UIViewController,
                               animated flag: Bool,
                               completion: (() -> Void)? = nil) {
    if #available(iOS 13.0, *) {
      if viewControllerToPresent.modalPresentationStyle == .automatic {
        viewControllerToPresent.modalPresentationStyle = .fullScreen
      }
    }
    swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
   }
}

Uso:
En su AppDelegateinterior application(_ application: didFinishLaunchingWithOptions)agregue esta línea:

UIViewController.swizzlePresent()

De esta manera, no necesita hacer ningún cambio en ninguna llamada actual, ya que estamos reemplazando la implementación del método actual en tiempo de ejecución.
Si necesita saber qué es swizzling, puede consultar este enlace: https://nshipster.com/swift-objc-runtime/

Abedalkareem Omreyh
fuente
Tengo muchos viewControllers en mi proyecto, pero no tengo clase base, no quiero swizzling, ¿tiene alguna solución para eso con cambios mínimos en el código?
Guru
Usé swizzling, pero agregué .pageSheet para condicionar ... if viewControllerToPresent.modalPresentationStyle == .pageSheet || viewControllerToPresent.modalPresentationStyle == .Automatic {viewControllerToPresent.modalPresentationStyle = .fullScreen}
Crash
la barra de estado se oculta cuando agrego la solución aplicada no 1.
Ganesh Pawar
44
Swizzling es una solución que funcionó muy bien por un tiempo. Sin embargo, cuando uso algunos sdks externos como FacebookLogin (5.8 a partir de hoy) y GoogleSignin, he notado que este método rompe esos flujos: obtenemos una pantalla en blanco en el iPad. Esto probablemente se deba al hecho de que usan su propio método de swizzling
Tao-Nhan Nguyen el
39

Solía ​​swizzling para ios 13

import Foundation
import UIKit

private func _swizzling(forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
    if let originalMethod = class_getInstanceMethod(forClass, originalSelector),
       let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) {
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}

extension UIViewController {

    static let preventPageSheetPresentation: Void = {
        if #available(iOS 13, *) {
            _swizzling(forClass: UIViewController.self,
                       originalSelector: #selector(present(_: animated: completion:)),
                       swizzledSelector: #selector(_swizzledPresent(_: animated: completion:)))
        }
    }()

    @available(iOS 13.0, *)
    @objc private func _swizzledPresent(_ viewControllerToPresent: UIViewController,
                                        animated flag: Bool,
                                        completion: (() -> Void)? = nil) {
        if viewControllerToPresent.modalPresentationStyle == .pageSheet
                   || viewControllerToPresent.modalPresentationStyle == .automatic {
            viewControllerToPresent.modalPresentationStyle = .fullScreen
        }
        _swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
    }
}

entonces pon esto

UIViewController.preventPageSheetPresentation

algun lado

por ejemplo en AppDelegate

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {

    UIViewController.preventPageSheetPresentation
    // ...
    return true
}
Maxime Ashurov
fuente
3
La solución más fácil si tienes múltiples modales.
Raisal Calicut
en algún lugar significa, en qué archivo o en qué parte del proyecto completo
Yatendra
en algún lugar, lo puse en appdelegate static letes perezoso, tienes que leerlo para que se calcule, var perezoso se calculó solo una vez, lo uso para garantizar que ese swizzling llame una vez
Maxime Ashurov
37

Para usuarios de Objective-C

Solo usa este código

 [vc setModalPresentationStyle: UIModalPresentationFullScreen];

O si desea agregarlo en particular en iOS 13.0, use

 if (@available(iOS 13.0, *)) {
     [vc setModalPresentationStyle: UIModalPresentationFullScreen];
 } else {
     // Fallback on earlier versions
 }
9to5ios
fuente
2
esto también funciona en versiones anteriores de ios, pero la respuesta es buena
Catalin el
44
UIModalPresentationFullScreen funciona con iOS 3.2+. Por lo tanto, no es necesario agregar si más condición.
flame3
2
Por alguna razón, en iOS 13.1.2 solo en las clases Obj-c esto no funciona y modalPresentationStyle solo muestra una hoja de página. ¿Esto está sucediendo para alguien más?
Sevy11
@ Sevy11 No he actualizado a iOS 13.1.2 pero funciona bien en 13.1
9to5ios
hola @ Sevy11 He actualizado mi iOS 13.1.2 y está funcionando bien, verifique al final
9to5ios
37

Un trazador de líneas:

modalPresentationStylese requiere que se configure en el NavigationController que se presenta .


iOS 13 y versiones anteriores de iOS fullScreen con overCurrentContext y navigationController

Código probado

let controller = UIViewController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navigationController, animated: true, completion: nil)

modalPresentationStyle requiere establecer en navigationController .

Pratik Sodha
fuente
Una aclaración: presentar un viewController desde un navigationController no necesita modalPresentationStyle para configurarse en navigationController. En cambio, se establece en el viewController que se presenta. Sin embargo, si presenta un control de navegación, entonces la propiedad 'modalPresentationStyle' debe establecerse en el control de navegación, no en el control de vista incrustado. Este enfoque funciona iOS 13.3, Xcode 11.3. Ver la respuesta de Yogesh Bharate.
Womble
@Pratik Sodha. ¿Alguna ayuda en esto? stackoverflow.com/questions/61429600/…
david
@Womble Cualquier ayuda en este stackoverflow.com/questions/61429600/…
david
25

Como una pista: Si llama a un presente ViewControllerque está incrustado dentro de una NavigationControllerque tiene que establecer la NavigationControllera .fullScreeny no el VC.

Puede hacer esto como @davidbates o hacerlo programáticamente (como @pascalbros).

Un escenario de ejemplo:

ingrese la descripción de la imagen aquí

    //BaseNavigationController: UINavigationController {}
    let baseNavigationController = storyboard!.instantiateViewController(withIdentifier: "BaseNavigationController")
    var navigationController = UINavigationController(rootViewController: baseNavigationController)
    navigationController.modalPresentationStyle = .fullScreen
    navigationController.topViewController as? LoginViewController
    self.present(navigationViewController, animated: true, completion: nil)
kuzdu
fuente
22

Necesitaba hacer las dos cosas:

  1. Establecer el estilo de presentación como pantalla completa

    Pantalla completa

  2. Establecer la barra superior como barra de navegación translúcida

Barra superior

vedrano
fuente
Es una suposición muy extraña que alguna opción en Simulated Metrics lo ayude a cambiar el estilo de presentación
Alexander Kulabukhov
14

Cambiar modalPresentationStyleantes de presentar

vc.modalPresentationStyle = UIModalPresentationFullScreen;
MAMN84
fuente
13

Aquí hay una solución fácil sin codificar una sola línea.

  • Seleccione View Controller en Storyboard
  • Seleccionar inspector de atributos
  • Establezca la presentación "Automática" en "Pantalla completa" como se muestra a continuación.

Este cambio hace que el funcionamiento de la aplicación iPad sea el esperado, de lo contrario, la nueva pantalla se muestra en el centro de la pantalla como una ventana emergente.

ingrese la descripción de la imagen aquí

Mahesh Cheliya
fuente
Creo que la clave aquí es que hiciste esto en el NavigationController, que es lo que muestra la imagen, pero el texto no lo dice de esta manera.
Andy Weinstein
1
también asegúrese de que los segmentos posteriores sean "Show" y no "Present Modally"
Andy Weinstein
Ok, este parece funcionar para mí cuando uso un controlador de barra de pestañas para controlar otras vistas. Sin embargo, debe establecer la Presentación del 'Controlador de barra de pestañas' real en Pantalla completa, ya que esto controla todas las demás vistas.
Charlie
12

Si tiene un UITabController con pantallas con controladores de navegación incorporados, debe configurar la presentación de UITabController en FullScreen como se muestra en la imagen a continuación

ingrese la descripción de la imagen aquí

Di Nerd
fuente
12

Aquí está la solución para Objective-C

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *vc = [storyBoard instantiateViewControllerWithIdentifier:@"ViewController"];

vc.modalPresentationStyle = UIModalPresentationFullScreen;

[self presentViewController:vc animated:YES completion:nil];
Prashanth Thota
fuente
11

Lo último para iOS 13 y Swift 5.x

let vc = ViewController(nibName: "ViewController", bundle: nil)

vc.modalPresentationStyle = .fullScreen

self.present(vc, animated: true, completion: nil)
Rubaiyat Jahan Mumu
fuente
9

Aquí está mi versión de corrección en ObjectiveC usando Categorías. Con este enfoque, tendrá el comportamiento predeterminado UIModalPresentationStyleFullScreen hasta que se establezca explícitamente otro.

#import "UIViewController+Presentation.h"
#import "objc/runtime.h"

@implementation UIViewController (Presentation)

- (void)setModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
    [self setPrivateModalPresentationStyle:modalPresentationStyle];
}

-(UIModalPresentationStyle)modalPresentationStyle {
    UIModalPresentationStyle style = [self privateModalPresentationStyle];
    if (style == NSNotFound) {
        return UIModalPresentationFullScreen;
    }
    return style;
}

- (void)setPrivateModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
    NSNumber *styleNumber = [NSNumber numberWithInteger:modalPresentationStyle];
     objc_setAssociatedObject(self, @selector(privateModalPresentationStyle), styleNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIModalPresentationStyle)privateModalPresentationStyle {
    NSNumber *styleNumber = objc_getAssociatedObject(self, @selector(privateModalPresentationStyle));
    if (styleNumber == nil) {
        return NSNotFound;
    }
    return styleNumber.integerValue;
}

@end
Alexander Kulabukhov
fuente
¿tienes el archivo .h?
Pedro Góes
@ PedroGóes sí, pero consiste solo en la declaración de categoría: `` `@interface UIViewController (Presentation) @end` ``
Alexander Kulabukhov
¡Usa esto si no quieres lidiar con todos los controladores en tu guión gráfico! Ahorrador de tiempo, gracias!
AnthoPak
7

Todas las otras respuestas son suficientes, pero para un proyecto grande como el nuestro y donde se realizan navegaciones tanto en código como en storyboard, es una tarea bastante desalentadora.

ingrese la descripción de la imagen aquí

Para aquellos que usan Storyboard activamente. Este es mi consejo: use Regex.

El siguiente formato no es bueno para páginas de pantalla completa:

<segue destination="Bof-iQ-svK" kind="presentation" identifier="importSystem" modalPresentationStyle="fullScreen" id="bfy-FP-mlc"/>

El siguiente formato es bueno para páginas de pantalla completa:

<segue destination="7DQ-Kj-yFD" kind="presentation" identifier="defaultLandingToSystemInfo" modalPresentationStyle="fullScreen" id="Mjn-t2-yxe"/>

La siguiente expresión regular compatible con VS CODE convertirá todas las páginas de estilo antiguo a nuevas páginas de estilo. Es posible que deba escapar de caracteres especiales si está utilizando otros motores de expresiones regulares / editores de texto.

Búsqueda Regex

<segue destination="(.*)"\s* kind="show" identifier="(.*)" id="(.*)"/>

Reemplazar Regex

<segue destination="$1" kind="presentation" identifier="$2" modalPresentationStyle="fullScreen" id="$3"/>
Bangonkali
fuente
4

Inicialmente, el valor predeterminado es fullscreenmodalPresentationStyle, pero en iOS 13 sus cambios a UIModalPresentationStyle.automatic.

Si desea hacer el controlador de vista de pantalla completa, debe cambiarlo modalPresentationStylea fullScreen.

Consulte UIModalPresentationStyle la documentación de Apple para obtener más detalles y consulte las pautas de la interfaz humana de Apple para saber dónde debe usar qué modalidad.

yo2bh
fuente
Esta es la respuesta correcta a partir de iOS 13.3, Xcode 11.3, para situaciones en las que desea presentar un viewController DESDE un navigationController. Un modalPresentationStyle de .overFullScreen también funciona. Sin embargo, si presenta un control de navegación, debe establecer 'modalPresentationStyle' en el control de navegación, no en el control de vista. Salud.
Womble
3

Puede hacerlo fácilmente Abra su guión gráfico como código fuente y busque kind="presentation", en toda la etiqueta seague con kind = presentation agregue un atributo adicionalmodalPresentationStyle="fullScreen"

amar
fuente
2
let Obj = MtViewController()
Obj.modalPresentationStyle = .overFullScreen
self.present(Obj, animated: true, completion: nil)

// si desea deshabilitar el deslizamiento para descartarlo, agregue una línea

Obj.isModalInPresentation = true

Consulte el documento de Apple para obtener más información.

Mohit Tomar
fuente
2

Lo logré usando el método swizzling (Swift 4.2):

Para crear una extensión UIViewController de la siguiente manera

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)
        }
    }
}

y en AppDelegate, en la aplicación: didFinishLaunchingWithOptions: invoque el código swizzling llamando:

UIViewController.setPresentationStyle_fullScreen()
Sreeraj VR
fuente
1

Esto funcionó para mí:

yourViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen

Dian
fuente
3
Esto no agrega nada a todas las otras respuestas existentes.
rmaddy
1

Cree una categoría para UIViewController (por ejemplo, UIViewController + PresentationStyle). Agregue el siguiente código.

 -(UIModalPresentationStyle)modalPresentationStyle{
     return UIModalPresentationStyleFullScreen;
}
Govind
fuente
esto romperá UISearchController + desencadenará un bloqueo difícil de depurar
dklt
@dklt Esa es una gran observación. Por lo tanto, establecer la propiedad explícitamente resolverá el problema. No hay soluciones más simples si UISearchController está utilizando.
Govind
0

un enfoque alternativo es tener su propio componente de controlador de vista base en su aplicación, y solo implementar los inicializadores designados y requeridos con una configuración básica, algo como lo siguiente:

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
    }
}

NOTA : Si su controlador de vista está contenido en un controlador de navegación que en realidad se presenta modalmente, entonces el controlador de navegación debe abordar el problema de la misma manera (es decir, tener su componente de controlador de navegación personalizado personalizado de la misma manera

Probado en Xcode 11.1 en iOS 13.1 y iOS 12.4

Espero eso ayude

Luca Iaco
fuente
0

Tuve este problema con un video que ya no se presenta a pantalla completa. Se agregó esta línea, que salvó el día :-)

videoController.modalPresentationStyle = UIModalPresentationFullScreen;
usuario1737746
fuente
2
Esto no agrega nada a todas las otras respuestas existentes.
rmaddy
0

La solución más simple que funcionó para mí.

viewController.modalPresentationStyle = .fullScreen
Fahad Azeem
fuente
3
Esto no agrega nada a todas las otras respuestas existentes.
rmaddy
0

Si está utilizando un UINavigationController e incrusta un ViewController como un controlador de vista raíz, entonces también se planteará el mismo problema. Use el siguiente código para superar.

let vc = UIViewController()
let navController = UINavigationController(rootViewController: vc)
navController.modalPresentationStyle = .fullScreen
Pramodya Abeysinghe
fuente
0
class MyViewController: UIViewController {

    convenience init() {
        self.init(nibName:nil, bundle:nil)
        self.modalPresentationStyle = .fullScreen
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

En lugar de llamar self.modalPresentationStyle = .fullScreena cada controlador de vista, puede subclasificar UIViewController y simplemente usarlo en MyViewControllertodas partes.

Peter Tao
fuente
-1

Las respuestas y sugerencias anteriores son correctas, a continuación hay otra versión y una manera eficiente de usar mediante programación.

# 1 creó una extensión UIView

# 2 creó un método ()

//#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)

  }
}

Invocando como abajo

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

O

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