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

现在它不是全屏默认情况下,当我向下滑动时,应用会自动解除视图控制器。

我怎么能防止这种行为,并回到旧的全屏模态vc?

谢谢


当前回答

我添加的信息可能对某人有用。如果你有任何故事板segue,要回到旧的风格,你需要将kind属性设置为modal Present,并将Presentation属性设置为全屏。

其他回答

最初,modalPresentationStyle的默认值是全屏,但在iOS 13中,它的变化是UIModalPresentationStyle.automatic。

如果你想要创建全屏视图控制器,你必须将modalPresentationStyle更改为fullScreen。

参考UIModalPresentationStyle苹果文档了解更多细节,并参考苹果人机界面指南了解应该在哪里使用哪种模式。

正如在2019年全球开发者大会上发布的平台国情咨文中所述,苹果在iOS 13中引入了新的默认卡显示方式。为了强制全屏,你必须明确地指定它:

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

为UIViewController创建一个类别(比如UIViewController+PresentationStyle)。向其添加以下代码。

 -(UIModalPresentationStyle)modalPresentationStyle{
     return UIModalPresentationStyleFullScreen;
}

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

然后放这个

UIViewController.preventPageSheetPresentation

的某个地方

例如在AppDelegate中

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

    UIViewController.preventPageSheetPresentation
    // ...
    return true
}

这里有一个简单的解决方案,无需编写任何代码。

在故事板中选择视图控制器 选择属性检查器 按照下图将显示“自动”设置为“全屏”

这一变化使iPad应用程序的行为符合预期,否则新屏幕将以弹出窗口的形式显示在屏幕中央。