在 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
Presenting modal in iOS 13 fullscreen
提问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?
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。
回答by davidbates
回答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 BaseViewController
you 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 present
call, as we just overrode the present
method.
使用这种方式,您无需对任何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
.
选择一个 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 AppDelegate
inside 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:
一个班轮:
modalPresentationStyle
is required to be set on the navigationControllerwhich is being presented.
modalPresentationStyle
需要在正在呈现的导航控制器上设置。
iOS 13 and below iOS version fullScreen with
overCurrentContext
andnavigationController
iOS 13 及以下 iOS 版本 fullScreen
overCurrentContext
和navigationController
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 ViewController
which is embedded inside a NavigationController
you have to set the NavigationController
to .fullScreen
and not the VC.
提示:如果您将present 调用到ViewController
嵌入在a 中的a ,则NavigationController
必须设置NavigationController
to.fullScreen
而不是VC。
You can do this like @davidbates or you do it programmatically (like @pascalbros).
您可以像@davidbates 那样执行此操作,也可以以编程方式(如@pascalbros)执行此操作。
An example scenario:
一个示例场景:
//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
回答by MAMN84
Change modalPresentationStyle
before presenting
modalPresentationStyle
呈现前改变
vc.modalPresentationStyle = UIModalPresentationFullScreen;