回答:
iOS 13では、WWDC 2019 のPlatforms State of the Unionで述べられているように、Appleは新しいデフォルトのカードプレゼンテーションを導入しました。全画面表示を強制するには、次のように明示的に指定する必要があります。
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
isModalInPresentation
スワイプジェスチャーが消えないようにブロックするために使用します。詳細については、私のブログ投稿を参照してください。medium.com
.automatic
スタイルはデフォルトのスタイルに落ち着きました。これは(ほとんどのビューコントローラの).pageSheet
スタイルです。ただし、システムビューコントローラーによっては、それを別のスタイルにマップする場合があります。
誰かに役立つ情報を追加します。ストーリーボードセグエがある場合、古いスタイルに戻すには、kindプロパティをPresent Modallyに、PresentationプロパティをFull Screenに設定する必要があります。
performSegue
。親愛なるありがとう!
これには複数の方法があり、それぞれが1つのプロジェクトに適合することはできるが、別のプロジェクトには適合しないと思うので、ここに置いておこうと思います。
を持っている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)
}
// ....
}
この方法を使用するpresent
と、present
メソッドをオーバーライドするだけなので、呼び出しを変更する必要はありません。
extension UIViewController {
func presentInFullScreen(_ viewController: UIViewController,
animated: Bool,
completion: (() -> Void)? = nil) {
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: animated, completion: completion)
}
}
使用法:
presentInFullScreen(viewController, animated: true)
let viewController = UIViewController()
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: true, completion: nil)
セグエを選択し、プレゼンテーションをに設定しFullScreen
ます。
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)
}
}
使用法:
あなたの中AppDelegate
の内側には、application(_ application: didFinishLaunchingWithOptions)
この行を追加します。
UIViewController.swizzlePresent()
この方法を使用すると、現在のメソッド実装をランタイムで置き換えるので、現在の呼び出しを変更する必要はありません。
何がスウィズリングしているかを知る必要がある場合は、次のリンクを確認できます。https:
//nshipster.com/swift-objc-runtime/
iOS 13でスウィズリングを使用しました
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
}
static let
が怠惰です、それを読み取って計算させるには、遅延varを1回だけ計算します。スウィズリングが1回呼び出されることを保証するために使用します
Objective-Cユーザー向け
このコードを使用するだけ
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
または、iOS 13.0で追加したい場合は、
if (@available(iOS 13.0, *)) {
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
} else {
// Fallback on earlier versions
}
一発ギャグ:
modalPresentationStyle
提示されているnavigationController で設定する必要があります。
iOS 13以前のiOSバージョンfullScreen
overCurrentContext
およびnavigationController
テストされたコード
let controller = UIViewController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navigationController, animated: true, completion: nil)
modalPresentationStyleは、navigationControllerで設定する必要があります。
ヒントとして:あなたが現在呼び出した場合ViewController
の内部に埋め込まれているNavigationController
あなたは、設定する必要がNavigationController
に.fullScreen
VC及びません。
@davidbatesのようにこれを行うか、(@ pascalbrosのように)プログラムで行うことができます。
シナリオ例:
//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)
これは、単一の行をコーディングせずに簡単な解決策です。
この変更により、iPadアプリは予想どおりに動作します。そうでない場合、新しい画面は画面の中央にポップアップとして表示されます。
これがObjective-Cのソリューションです
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *vc = [storyBoard instantiateViewControllerWithIdentifier:@"ViewController"];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:nil];
iOS 13およびSwift 5.xの最新
let vc = ViewController(nibName: "ViewController", bundle: nil)
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)
これは、カテゴリを使用したObjectiveCでの修正バージョンです。このアプローチでは、別のアクションが明示的に設定されるまで、デフォルトのUIModalPresentationStyleFullScreenの動作になります。
#import "UIViewController+Presentation.h"
#import "objc/runtime.h"
@implementation UIViewController (Presentation)
- (void)setModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
[self setPrivateModalPresentationStyle:modalPresentationStyle];
}
-(UIModalPresentationStyle)modalPresentationStyle {
UIModalPresentationStyle style = [self privateModalPresentationStyle];
if (style == NSNotFound) {
return UIModalPresentationFullScreen;
}
return style;
}
- (void)setPrivateModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
NSNumber *styleNumber = [NSNumber numberWithInteger:modalPresentationStyle];
objc_setAssociatedObject(self, @selector(privateModalPresentationStyle), styleNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIModalPresentationStyle)privateModalPresentationStyle {
NSNumber *styleNumber = objc_getAssociatedObject(self, @selector(privateModalPresentationStyle));
if (styleNumber == nil) {
return NSNotFound;
}
return styleNumber.integerValue;
}
@end
他のすべての答えで十分ですが、私たちのような大規模なプロジェクトで、コードとストーリーボードの両方でナビゲーションが行われている場合、それは非常に困難な作業です。
Storyboardを積極的に使用している人向け。これは私のアドバイスです:Regexを使用してください。
次の形式は、フルスクリーンページには適していません。
<segue destination="Bof-iQ-svK" kind="presentation" identifier="importSystem" modalPresentationStyle="fullScreen" id="bfy-FP-mlc"/>
次の形式は、全画面ページに適しています。
<segue destination="7DQ-Kj-yFD" kind="presentation" identifier="defaultLandingToSystemInfo" modalPresentationStyle="fullScreen" id="Mjn-t2-yxe"/>
VS CODEと互換性のある次の正規表現は、すべての古いスタイルのページを新しいスタイルのページに変換します。他の正規表現エンジン/テキストエディタを使用している場合は、特殊文字をエスケープする必要がある場合があります。
正規表現を検索
<segue destination="(.*)"\s* kind="show" identifier="(.*)" id="(.*)"/>
正規表現を置き換える
<segue destination="$1" kind="presentation" identifier="$2" modalPresentationStyle="fullScreen" id="$3"/>
最初は、デフォルト値はfullscreen
modalPresentationStyleですが、iOS 13ではに変更されていUIModalPresentationStyle.automatic
ます。
フルスクリーンのビューコントローラを作成する場合は、をに変更するmodalPresentationStyle
必要がありfullScreen
ます。
詳細についてはUIModalPresentationStyle
アップルのドキュメントを参照してください。また、モダリティをどこで使用するかについては、アップルのヒューマンインターフェイスガイドラインを参照してください。
let Obj = MtViewController()
Obj.modalPresentationStyle = .overFullScreen
self.present(Obj, animated: true, completion: nil)
//スワイプを無効にして無効にする場合は、行を追加します
Obj.isModalInPresentation = true
詳しくはApple Documentを確認してください。
私はメソッドswizzling(Swift 4.2)を使用してそれを達成しました:
次のようにUIViewController拡張機能を作成するには
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)
}
}
}
AppDelegateのapplication:didFinishLaunchingWithOptions:次の呼び出しでスウィズリングコードを呼び出します。
UIViewController.setPresentationStyle_fullScreen()
UIViewController(たとえば、UIViewController + PresentationStyle)のカテゴリを作成します。次のコードを追加します。
-(UIModalPresentationStyle)modalPresentationStyle{
return UIModalPresentationStyleFullScreen;
}
別のアプローチは、アプリに独自のベースビューコントローラーコンポーネントを配置し、次のような基本的なセットアップで指定された必要な初期化子を実装することです。
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
}
}
注意:ビューコントローラーが実際にモーダルで表示されるナビゲーションコントローラーに含まれている場合、ナビゲーションコントローラーは同じ方法で問題に対処する必要があります(つまり、カスタムナビゲーションコントローラーコンポーネントを同じ方法でカスタマイズします)
iOS 13.1およびiOS 12.4のXcode 11.1でテスト済み
それが役に立てば幸い
フルスクリーンを表示しないビデオでこの問題が発生しました。この日を救ったこの行を追加しました:-)
videoController.modalPresentationStyle = UIModalPresentationFullScreen;
UINavigationControllerを使用していて、ViewControllerをルートビューコントローラーとして埋め込む場合も、同じ問題が発生します。克服するために次のコードを使用してください。
let vc = UIViewController()
let navController = UINavigationController(rootViewController: vc)
navController.modalPresentationStyle = .fullScreen
class MyViewController: UIViewController {
convenience init() {
self.init(nibName:nil, bundle:nil)
self.modalPresentationStyle = .fullScreen
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
self.modalPresentationStyle = .fullScreen
すべてのビューコントローラを呼び出すのではなく、UIViewControllerをサブクラス化しMyViewController
て、どこでも使用できます。
上記の回答と提案は正しいですが、以下は別のバージョンであり、プログラムで使用する効率的な方法です。
#1 UIView拡張を作成
#2メソッドを作成した()
//#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)
または
let vc = MyViewController()
sourceView.presentLocal(vc, animated: true, completion: nil)
fullScreen
UIの変更を壊さないようにするには、このオプションをデフォルトにする必要があります。