Presenting modal in iOS 13 fullscreen
Asked Answered
M

28

649

In iOS 13 there is a new behaviour for modal view controller when being presented.

Now it's not fullscreen by default and when I try to slide down, the app just dismiss the View Controller automatically.

How can I prevent this behaviour and get back to the old fullscreen modal vc?

modal behaviour

Thanks

Microsporangium answered 3/6, 2019 at 23:1 Comment(0)
M
839

With iOS 13, as stated in the Platforms State of the Union during the WWDC 2019, Apple introduced a new default card presentation. In order to force the fullscreen you have to specify it explicitly with:

let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
Microsporangium answered 3/6, 2019 at 23:1 Comment(9)
I won't count on that. In the past, Apple has often changed defaults only becoming active once you are linking against the current SDK. We will hopefully get the old behavior when linking against previous versions.Nejd
I can confirm that Xcode-10 built apps run on the iOS 13 simulator do still default to full screen. As @Nejd said, building with Xcode 11 opts the app in to the new behaviour. Use isModalInPresentation to block the swipe gesture from dismissing. See my blog post for more details: medium.com/@hacknicity/…Gremlin
In .compact horizontal size class .fullScreen presentation does not act exactly as .formSheet in iOS 12. You should use .overFullScreen mode in order to fully replicate the old behavior.Delossantos
I recommend to use .fullScreen instead of .overFullScreen. .fullScreen fires viewWillAppear and viewDidAppear, .overFullScreen doesn't do thatGetup
Time has passed and the .automatic style has settled down as the default one, which is (for most view controllers) .pageSheet style. However some system view controllers may map it to a different style.Dele
No luck with this with MFMessageComposeViewController. Setting to fullScreen but it stays in the new card format.Suppurate
How would you close this VC?Treacherous
Keep in mind that if you use a navigation controller, the modalPresentationStyle should be added to the navigation controller, not the presented view controller.Stoss
@JAWS007 You can call dismiss(animated: completion:), either from the VC that presents it or the VC that was presented. It will remove the topmost VC from the navigation stack.Stoss
J
252

I add an information that could be useful for someone. If you have any storyboard segue, to go back to the old style, you need to set the kind property to Present Modally and the Presentation property to Full Screen.

enter image description here

Jeer answered 10/6, 2019 at 16:27 Comment(2)
Is there a way in Interface Builder to set isModalInPresentation?Alisa
You just solved my problem, thank you! 3 days of fiddling...Stylo
H
130

I had this issue on the initial view right after the launch screen. The fix for me since I didn't have a segue or logic defined was to switch the presentation from automatic to fullscreen as shown here:

fix_storyboard_presentation_default_behavior

Heloise answered 18/8, 2019 at 17:32 Comment(3)
Is there any way to do this programmatically for all views instead of one by one through storyboard?Unilobed
@ShobhitPuri Have a look at the first solution by Omreyh here https://mcmap.net/q/57025/-presenting-modal-in-ios-13-fullscreenUnilobed
Wow, this was THE answer for my issues. Thanks for the tip! For any others looking into this as well, this is the fix for strange behaviour after reopening the app from the background. In my application, opening from the background would overlay my splash screen (initial view controller) as a card presentation style and then any segues from here on out would cross-fade instead of using my defined segue style. It would be fine if I closed the app (double tap home button and swipe up, then reopen) but any additional launches would cause this strange behaviour. Thanks again!Amend
I
122

There are multiple ways to do that, and I think each one could fit for one project but not another, so I thought I'll keep them here maybe someone else will run to a different case.

1- Override present

If you have a BaseViewController you can override the present(_ viewControllerToPresent: animated flag: completion:) method.

class BaseViewController: UIViewController {

  // ....

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

  // ....
}

Using this way you don't need to do any change on any present call, as we just overrode the present method.

2- An extension:

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

Usage:

presentInFullScreen(viewController, animated: true)

3- For one UIViewController

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

4- From Storyboard

Select a segue and set the presentation to FullScreen.
enter image description here

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

Usage:
In your AppDelegate inside application(_ application: didFinishLaunchingWithOptions) add this line:

UIViewController.swizzlePresent()

Using this way you don't need to do any change on any present call, as we are replacing the present method implementation in runtime.
If you need to know what is swizzling you can check this link: https://nshipster.com/swift-objc-runtime/

Icarus answered 6/10, 2019 at 8:13 Comment(4)
I have many viewControllers in my project, but do not have base class, i don't want swizzling do you have any solution for that with minimum changes in codeSlaty
I used swizzling, but I added .pageSheet to condition.... if viewControllerToPresent.modalPresentationStyle == .pageSheet || viewControllerToPresent.modalPresentationStyle == .automatic { viewControllerToPresent.modalPresentationStyle = .fullScreen }Handicapped
status bar is hiding when I add applied solution no 1.Lambert
Swizzling is a solution that worked great for a while. However, when using some external sdks such as FacebookLogin (5.8 as of today) and GoogleSignin, I have noticed that this method breaks those flows : we get a white screen on iPad. This is probably due to the fact that they use their own swizzling methodBlunk
T
48

As a hint: If you call present to a ViewController which is embedded inside a NavigationController you have to set the NavigationController to .fullScreen and not the VC.

You can do this like @davidbates or you do it programmatically (like @pascalbros).

The same applies to the UITabViewController

An example scenario for NavigationController:

enter image description here

    //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)
Trixie answered 10/9, 2019 at 9:11 Comment(1)
This is a really useful point. Really easy to forget and drive you crazy (I did). ThanksArbuckle
R
48

For Objective-C users

Just Use this code

 [vc setModalPresentationStyle: UIModalPresentationFullScreen];

Or if you want to add it particular in iOS 13.0 then use

 if (@available(iOS 13.0, *)) {
     [vc setModalPresentationStyle: UIModalPresentationFullScreen];
 } else {
     // Fallback on earlier versions
 }
Romona answered 24/9, 2019 at 11:40 Comment(3)
UIModalPresentationFullScreen works with iOS 3.2+. So no need to add if else condition.Transect
For some reason in iOS 13.1.2 only in Obj-c classes this is not working and modalPresentationStyle is only displaying a pageSheet. Is this happening for anyone else?Ancillary
@Ancillary I have not updated to iOS 13.1.2 but working fine at 13.1Romona
H
46

One Liner:

modalPresentationStyle is required to be set on the navigationController which is being presented.


iOS 13 and below iOS version fullScreen with overCurrentContext and navigationController

Tested Code

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

modalPresentationStyle require to set at navigationController.

Hick answered 27/11, 2019 at 7:21 Comment(1)
A clarification: presenting a viewController from a navigationController does not need modalPresentationStyle to be set on the navigationController. Instead, it is set on the viewController being presented. However, if you are presenting a navigationController, then the 'modalPresentationStyle' property should be set on the navigationController, not the embedded viewController. This approach works iOS 13.3, Xcode 11.3. See Yogesh Bharate's answer.Decennary
B
42

This worked for me

let vc = self.storyboard?.instantiateViewController(withIdentifier: "storyboardID_cameraview1") as! CameraViewController
  
vc.modalPresentationStyle = .fullScreen
    
self.present(vc, animated: true, completion: nil)`
Baden answered 1/11, 2020 at 3:34 Comment(0)
R
41

I used swizzling for 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)
    }
}

then put this

UIViewController.preventPageSheetPresentation

somewhere

for example in AppDelegate

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

    UIViewController.preventPageSheetPresentation
    // ...
    return true
}
Resht answered 2/10, 2019 at 16:29 Comment(2)
Using this we are having the below error for some devices Fatal Exception: NSInternalInconsistencyException Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.Matriculate
it's weird, checkout if it happens without swizzling, (comment this line UIViewController.preventPageSheetPresentation), if it still happens find the actual issue, you call some layout somewhere in background thread (I guess in completion of network request)Resht
P
29

Latest for iOS 13 and Swift 5.x

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

vc.modalPresentationStyle = .fullScreen

self.present(vc, animated: true, completion: nil)
Prickle answered 6/4, 2020 at 15:47 Comment(0)
M
28

I needed to do both:

  1. Set presentation style as Full screen

    Full screen

  2. Set Top bar as Translucent Navigation Bar

Top bar

Macaroni answered 27/11, 2019 at 9:54 Comment(2)
It's a very strange assumption that some option in Simulated Metrics helps you change presentation styleBibbie
@AlexanderKulabukhov it doesn't. It's purely simulated.Sororicide
A
21

Quick solution. There are already really great answers above. I am also adding my quick 2 points input, which is presented in the screenshot.

  1. If you are not using Navigation Controller then from Right Menu Inspector set the Presentation to Full Screen

  2. If you are using Navigation Controller then by default it will present full screen, you have to do nothing.

enter image description here

Alby answered 9/7, 2020 at 11:37 Comment(1)
Yeap, That's pretty much it... Thanks... I don't know why the code line is not working for one particular UI, but others are working fine with the code... this seems to be the only one with storyboard though, and having code is not working issue... but when I do like this from storyboard's properties, this fixed. saved the day...Tug
L
13

Here is an easy solution without coding a single line.

  • Select View Controller in Storyboard
  • Select attribute Inspector
  • Set presentation "Automatic" to "FullScreen" as per below image

This change makes iPad app behavior as expected otherwise the new screen is displaying in the center of the screen as a popup.

enter image description here

Latanya answered 19/10, 2019 at 11:29 Comment(3)
I think that what is key here is that you did this on the NavigationController, which is what the picture shows but the text does not say it this way.Novercal
also make sure subsequent segues are "Show" and not "Present Modally"Novercal
Ok, so this one seems to work for me when I use a tab bar controller to control other views. However, you need to set the Presentation of the actual 'Tab Bar Controller' to Full Screen as this controls all other views.Rhee
P
13

Here is the solution for Objective-C

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

vc.modalPresentationStyle = UIModalPresentationFullScreen;

[self presentViewController:vc animated:YES completion:nil];
Purificator answered 13/11, 2019 at 7:4 Comment(0)
L
12

If you have a UITabController with Screens with Embeded Navigation Controllers, you have to set the UITabController Presentation to FullScreen as shown in pic below

enter image description here

Langlois answered 23/9, 2019 at 17:38 Comment(0)
L
10

Setting navigationController.modalPresentationStyle to .fullScreen has been repeated here more than a thousand times but let me present you another blocker which was causing that UIViewController / UINavigationController was not showing in fullscreen even though all the properties were set properly.

In my case the culprit was hidden in this line

navigationController?.presentationController?.delegate = self

Apparently when setting UIAdaptivePresentationControllerDelegate you need to specify the presentation style within the optional delegate method

    public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        presentationStyle
    }
Lorenzen answered 26/3, 2021 at 6:45 Comment(0)
B
9

Here's my version of fix in ObjectiveC using Categories. With this approach you'll have default UIModalPresentationStyleFullScreen behaviour until another one explicitly set.

#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
Bibbie answered 3/12, 2019 at 17:24 Comment(2)
do you have the .h file?Carousel
@PedroGóes yep, but it consist only of category declaration: ``` @interface UIViewController (Presentation) @end ```Bibbie
S
8

All the other answers are sufficient but for a large project like ours and where navigations are being made both in code and storyboard, it is quite a daunting task.

enter image description here

For those who are actively using Storyboard. This is my advice: use Regex.

The following format is not good for full screen pages:

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

The following format is good for full screen pages:

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

The following regex compatible with VS CODE will convert all Old Style pages to new style pages. You may need to escape special chars if you're using other regex engines/text editors.

Search Regex

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

Replace Regex

<segue destination="$1" kind="presentation" identifier="$2" modalPresentationStyle="fullScreen" id="$3"/>
Shedevil answered 25/10, 2019 at 15:1 Comment(0)
K
6

With iOS 13, as stated in the Platforms State of the Union during the WWDC 2019, Apple introduced a new default card presentation. In order to force the fullscreen you have to specify it explicitly with:

let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.navigationViewController.present(vc, animated: true, completion: nil)
Kilby answered 13/6, 2023 at 15:19 Comment(0)
V
5

Initially, the default value is fullscreen for modalPresentationStyle, but in iOS 13 its changes to the UIModalPresentationStyle.automatic.

If you want to make the full-screen view controller you have to change the modalPresentationStyle to fullScreen.

Refer UIModalPresentationStyle apple documentation for more details and refer apple human interface guidelines for where should use which modality.

Vanish answered 6/11, 2019 at 6:43 Comment(1)
This is the correct answer as of iOS 13.3, Xcode 11.3, for situations where you want to present a viewController FROM a navigationController. A modalPresentationStyle of .overFullScreen also works. However, if you are presenting a navigationController, then you need to set 'modalPresentationStyle' on the navigationController, not the viewController. Cheers.Decennary
S
3
let Obj = MtViewController()
Obj.modalPresentationStyle = .overFullScreen
self.present(Obj, animated: true, completion: nil)

// if you want to disable swipe to dismiss on it, add line

Obj.isModalInPresentation = true

Check Apple Document for More info.

Sanctimony answered 25/9, 2019 at 10:33 Comment(0)
P
3

You can easily do so Open your storyboard as source code and search for kind="presentation", in all the seague tag with kind = presentation add a extra attribute modalPresentationStyle="fullScreen"

Penultimate answered 26/11, 2019 at 7:54 Comment(0)
G
3

I achieved it by using method swizzling(Swift 4.2):

To create an UIViewController extension as follows

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

and in AppDelegate, in application:didFinishLaunchingWithOptions: invoke the swizzling code by calling:

UIViewController.setPresentationStyle_fullScreen()
Gaudreau answered 24/5, 2020 at 11:37 Comment(2)
Very hacky solution. You could have achieved same result with regular UIViewController subclass and avoid swizzling. Now if I extract some screens into framework, I will not have the swizzled methods there. Needless to say this is hard to locate if you inherit the project. You should avoid swizzling like a plague. Will not give -1 as it does solve problem, but breaks SOLID as now AppDelegate is needed to configure View Controllers and can make mess in future iOS versions.Beget
@MartinBerger , the solution will be useful if you try to migrate your old code to new and It is not recommended for the new projects.Gaudreau
A
1

Create a category for UIViewController (say UIViewController+PresentationStyle). Add the following code to it.

 -(UIModalPresentationStyle)modalPresentationStyle{
     return UIModalPresentationStyleFullScreen;
}
Anchoveta answered 25/11, 2019 at 9:40 Comment(2)
this will break UISearchController + trigger some hard to debug crashShanonshanta
@Shanonshanta That's a great observation. So setting the property explicitly will solve the issue. No simpler solutions if UISearchController is using.Anchoveta
A
1

override modalPresentationStyle will fix the style for UIViewControllers created with or without a coder.

Advantages:

  • Single place where you set it.
  • No need to know which init or awake method it should be set

Disadvantage:

  • You can't change it from outside like Interface builder or configuration from code

Solution:

override var modalPresentationStyle: UIModalPresentationStyle {
    get { .fullScreen }
    set { }
}
Affianced answered 15/12, 2022 at 12:53 Comment(0)
L
0

an alternative approach is to have your own base viewcontroller component in your app, and just implementing the designated and required initialisers with a basic setup, something like the following:

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: If your view controller is contained in a navigation controller which is actually presented modally, then the navigation controller should approach the problem in the same way (meaning, having your custom navigation controller component customised in the same way

Tested on Xcode 11.1 on iOS 13.1 and iOS 12.4

Hope it helps

Lanceted answered 9/10, 2019 at 7:42 Comment(0)
D
-1

The above answers and suggestions are right, below is another version, and efficient way using programmatically.

#1 Created a UIView Extension

#2 Created a Method ()

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

  }
}

Invoking as below

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

OR

let vc = MyViewController()
sourceView.presentLocal(vc, animated: true, completion: nil)
Diandrous answered 5/10, 2019 at 11:22 Comment(0)
A
-1
class MyViewController: UIViewController {

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

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

Rather than call self.modalPresentationStyle = .fullScreen for every view controller, you can subclass UIViewController and just use MyViewController everywhere.

Asleyaslope answered 18/10, 2019 at 6:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.