在 iOS 13 全屏显示模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/56435510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:51:47  来源:igfitidea点击:

Presenting modal in iOS 13 fullscreen

iosviewcontrollermodalviewcontrollerios13

提问by pascalbros

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

在 iOS 13 中,模态视图控制器在呈现时有一个新行为。

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?

如何防止这种行为并回到旧的全屏模式 vc?

modal behaviour

模态行为

Thanks

谢谢

回答by pascalbros

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

在 iOS 13 中,正如WWDC 2019 期间的平台国情咨文所述,Apple 引入了新的默认卡片展示。为了强制全屏,您必须明确指定它:

let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)

回答by Alessandro

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 kindproperty to Present Modallyand the Presentationproperty to Full Screen.

我添加了一个可能对某人有用的信息。如果您有任何故事板转场,要回到旧样式,您需要将kind属性设置为Present Modally并将Presentation属性设置为Full Screen

enter image description here

在此处输入图片说明

回答by davidbates

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:

我在启动屏幕后的初始视图中遇到了这个问题。因为我没有定义 segue 或逻辑,所以我的解决方法是将演示文稿从自动切换到全屏,如下所示:

fix_storyboard_presentation_default_behavior

fix_storyboard_presentation_default_behavior

回答by Abedalkareem Omreyh

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

1- 覆盖存在

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

如果你有一个BaseViewController你可以覆盖该present(_ viewControllerToPresent: animated flag: completion:)方法。

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 presentcall, as we just overrode the presentmethod.

使用这种方式,您无需对任何present调用进行任何更改,因为我们只是覆盖了该present方法。

2- An extension:

2- 扩展:

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

3- 对于一个 UIViewController

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

4- From Storyboard

4- 从故事板

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

选择一个 segue 并将演示文稿设置为FullScreen.
在此处输入图片说明

5- Swizzling

5- 调酒

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 AppDelegateinside application(_ application: didFinishLaunchingWithOptions)add this line:

用法:
在你的AppDelegate里面application(_ application: didFinishLaunchingWithOptions)添加这一行:

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/

使用这种方式,您无需对任何当前调用进行任何更改,因为我们正在运行时替换当前方法实现。
如果您需要知道什么是 swizzling,您可以查看此链接:https: //nshipster.com/swift-objc-runtime/

回答by Maxime Ashurov

I used swizzling for ios 13

我为 ios 13 使用了 swizzling

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

例如在 AppDelegate

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

    UIViewController.preventPageSheetPresentation
    // ...
    return true
}

回答by 9to5ios

For Objective-C users

对于 Objective-C 用户

Just Use this code

只需使用此代码

 [vc setModalPresentationStyle: UIModalPresentationFullScreen];

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

或者,如果您想在 iOS 13.0 中添加它,请使用

 if (@available(iOS 13.0, *)) {
     [vc setModalPresentationStyle: UIModalPresentationFullScreen];
 } else {
     // Fallback on earlier versions
 }

回答by Pratik Sodha



One Liner:

一个班轮:

modalPresentationStyleis required to be set on the navigationControllerwhich is being presented.

modalPresentationStyle需要在正在呈现导航控制器上设置。



iOS 13 and below iOS version fullScreen with overCurrentContextand navigationController

iOS 13 及以下 iOS 版本 fullScreenoverCurrentContextnavigationController

Tested Code

测试代码

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

modalPresentationStylerequire to set at navigationController.

modalPresentationStyle需要在navigationController 中设置。

回答by kuzdu

As a hint: If you call present to a ViewControllerwhich is embedded inside a NavigationControlleryou have to set the NavigationControllerto .fullScreenand not the VC.

提示:如果您将present 调用到ViewController嵌入在a 中的a ,则NavigationController必须设置NavigationControllerto.fullScreen而不是VC。

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

您可以像@davidbates 那样执行此操作,也可以以编程方式(如@pascalbros)执行此操作。

An example scenario:

一个示例场景:

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)

回答by vedrano

I needed to do both:

我需要同时做:

  1. Set presentation style as Full screen

    Full screen

  2. Set Top bar as Translucent Navigation Bar

  1. 将演示样式设置为全屏

    全屏

  2. 将顶部栏设置为半透明导航栏

Top bar

顶栏

回答by MAMN84

Change modalPresentationStylebefore presenting

modalPresentationStyle呈现前改变

vc.modalPresentationStyle = UIModalPresentationFullScreen;