在iOS 13中,模态视图控制器在呈现时有一个新的行为。
现在它不是全屏默认情况下,当我向下滑动时,应用会自动解除视图控制器。
我怎么能防止这种行为,并回到旧的全屏模态vc?
谢谢
在iOS 13中,模态视图控制器在呈现时有一个新的行为。
现在它不是全屏默认情况下,当我向下滑动时,应用会自动解除视图控制器。
我怎么能防止这种行为,并回到旧的全屏模态vc?
谢谢
当前回答
正如在2019年全球开发者大会上发布的平台国情咨文中所述,苹果在iOS 13中引入了新的默认卡显示方式。为了强制全屏,你必须明确地指定它:
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
其他回答
我在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
}
以上的答案和建议是正确的,下面是另一个版本,和有效的方法使用编程。
创建一个UIView扩展
创建一个方法()
//#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)
}
}
调用如下所示
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)
另一种方法是在你的应用程序中拥有你自己的基本视图控制器组件,并通过一个基本的设置来实现指定的和必需的初始化器,如下所示:
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
}
}
注意:如果你的视图控制器包含在一个以模态方式呈现的导航控制器中,那么导航控制器应该以同样的方式处理这个问题(也就是说,用同样的方式定制你的自定义导航控制器组件)
在Xcode 11.1、iOS 13.1和iOS 12.4上测试
希望能有所帮助
一个衬套:
modalPresentationStyle需要在正在呈现的navigationController上设置。
iOS 13及以下的iOS版本fullScreen with overCurrentContext和 导航控制器
经过测试的代码
let controller = UIViewController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navigationController, animated: true, completion: nil)
modalPresentationStyle需要设置在navigationController。
override modalPresentationStyle将修复使用或不使用编码器创建的UIViewControllers的样式。
优点:
你放置它的唯一位置。 不需要知道应该设置哪个init或awake方法
劣势:
你不能从外部改变它,像接口构建器或配置从代码
解决方案:
override var modalPresentationStyle: UIModalPresentationStyle {
get { .fullScreen }
set { }
}