답변:
WWDC 2019 에서 Platforms of the Union에 언급 된대로 iOS 13을 사용하여 Apple은 새로운 기본 카드 프리젠 테이션을 도입했습니다. 전체 화면을 강제 실행하려면 다음과 같이 명시 적으로 지정해야합니다.
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
isModalInPresentation
스 와이프 제스처가 사라지지 않도록 차단하는 데 사용 합니다. 자세한 내용은 내 블로그 게시물을 참조하십시오. medium.com/@hacknicity/…
.automatic
스타일이 기본 시간으로 정해졌습니다 (대부분의 뷰 컨트롤러의 경우) .pageSheet
. 그러나 일부 시스템 뷰 컨트롤러는이를 다른 스타일로 매핑 할 수 있습니다.
누군가에게 유용한 정보를 추가합니다. 스토리 보드 segue가있는 경우 이전 스타일로 돌아가려면 kind 속성을 Present Modally 로 설정 하고 Presentation 속성을 Full Screen 으로 설정해야합니다 .
performSegue
. 고마워, 여보!
시작 화면 직후의 초기보기 에서이 문제가 발생했습니다. 정의 또는 논리가 정의되지 않았기 때문에 해결 방법은 다음과 같이 프레젠테이션을 자동에서 전체 화면으로 전환하는 것이 었습니다.
여러 가지 방법이 있으며 각 프로젝트는 하나의 프로젝트에는 적합하지만 다른 프로젝트에는 적합하지 않다고 생각하므로 다른 사람이 다른 사건을 겪을 수도 있습니다.
있는 경우 메소드를 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)
segue를 선택하고 프레젠테이션을로 설정하십시오 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에 한 번만 계산, 내가 한 번만 호출 스위 즐링 보장을 가지고 그것을 사용
Objective-C 사용자의 경우
이 코드를 사용하십시오
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
또는 iOS 13.0에서 특정 항목을 추가하려면
if (@available(iOS 13.0, *)) {
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
} else {
// Fallback on earlier versions
}
짧막 한 농담:
modalPresentationStyle
표시되는 navigationController에서 설정해야합니다 .
아이폰 OS (13)와 아이폰 OS 버전의 전체 화면 아래
overCurrentContext
및navigationController
테스트 된 코드
let controller = UIViewController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navigationController, animated: true, completion: nil)
modalPresentationStyle 은 navigationController 에서 설정해야합니다 .
힌트로 : ViewController
안에 포함 된 에 대한 전화를 하면 VC가 아닌 NavigationController
로 설정해야 NavigationController
합니다 .fullScreen
.
@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
다른 모든 대답은 충분하지만 우리와 같은 큰 프로젝트와 코드와 스토리 보드 모두에서 탐색이 수행되는 곳은 상당히 어려운 작업입니다.
스토리 보드를 적극적으로 사용하는 사람들을 위해. 이것은 내 조언입니다 : 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
애플 설명서 를 참조하고 어느 양식을 사용해야하는지에 대한 애플 휴먼 인터페이스 지침 을 참조하십시오 .
스위 즐링 방법 (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;
}
다른 방법은 앱에 자체 기본 뷰 컨트롤러 구성 요소를 배치하고 다음과 같은 기본 설정으로 지정된 초 기자 (initializer)를 구현하는 것입니다.
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 변경을 중단하지 않으려면 이 옵션이 기본값이어야합니다.