Presenting modal in iOS 13 fullscreen

后端 未结 30 2131
囚心锁ツ
囚心锁ツ 2020-11-21 06:48

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 dis

相关标签:
30条回答
  • 2020-11-21 07:10

    If you are using a UINavigationController and embed a ViewController as a root view controller, then also you would rise up with same issue. Use following code to overcome.

    let vc = UIViewController()
    let navController = UINavigationController(rootViewController: vc)
    navController.modalPresentationStyle = .fullScreen
    
    0 讨论(0)
  • 2020-11-21 07:11

    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];
    
    0 讨论(0)
  • 2020-11-21 07:11

    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.

    0 讨论(0)
  • 2020-11-21 07: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

    0 讨论(0)
  • 2020-11-21 07:12

    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

    0 讨论(0)
  • 2020-11-21 07:14

    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()
    
    0 讨论(0)
提交回复
热议问题