iOS 13 전체 화면에서 모달 표시
iOS 13 Beta 1에는 모달 뷰 컨트롤러가 표시 될 때 새로운 동작이 있습니다. 이제 기본적으로 전체 화면이 아니며 아래로 슬라이드하려고하면 앱이 View Controller를 자동으로 닫습니다.
이 동작을 방지하고 오래된 좋은 전체 화면 모달 vc로 돌아가려면 어떻게해야합니까?
감사
WWDC 2019 기간 동안 Platforms of the Union에 명시된 바와 같이 , Apple은 새로운 기본 카드 프레젠테이션을 iOS 13과 함께 발표했습니다. 전체 화면을 강제 실행하려면 다음과 같이 명시 적으로 지정해야합니다.
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
누군가에게 유용한 정보를 추가합니다. 스토리 보드 segue가있는 경우 이전 스타일로 돌아가려면 kind 속성을 Present Modally 로 설정 하고 Presentation 속성을 Full Screen 으로 설정해야합니다 .
시작 화면 직후의 초기보기 에서이 문제가 발생했습니다. segue 또는 논리가 정의되지 않았기 때문에 해결 방법은 다음과 같이 프레젠테이션을 자동에서 전체 화면으로 전환하는 것이 었습니다.
힌트로 : 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)
Objective-C 사용자의 경우
이 코드를 사용하십시오
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
또는 iOS 13.0에서 특정 항목을 추가하려면
if (@available(iOS 13.0, *)) {
[vc setModalPresentationStyle: UIModalPresentationFullScreen];
} else {
// Fallback on earlier versions
}
임베디드 내비게이션 컨트롤러가있는 스크린이있는 UITabController가있는 경우 아래 그림과 같이 UITabController 프리젠 테이션 을 전체 화면으로 설정해야 합니다.
let Obj = MtViewController()
Obj.modalPresentationStyle = .overFullScreen
self.present(Obj, animated: true, completion: nil)
// 스 와이프하여 사용하지 않도록 설정하려면 줄을 추가하십시오.
Obj.isModalInPresentation = true
자세한 정보는 Apple 문서 를 확인하십시오 .
여러 가지 방법이 있으며 각 프로젝트는 하나의 프로젝트에는 적합하지만 다른 프로젝트에는 적합하지 않다고 생각하므로 다른 사람이 다른 사건을 겪을 수도 있습니다.
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
메소드를 오버로딩하기 때문에 모든 호출에서 변경을 수행 할 필요가 없습니다 .
2- 소멸 :
extension UIViewController {
func presentInFullScreen(_ viewController: UIViewController,
animated: Bool,
completion: (() -> Void)? = nil) {
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: animated, completion: completion)
}
}
용법:
presentInFullScreen(viewController, animated: true)
3- 하나의 뷰 컨트롤러
let viewController = UIViewController()
viewController.modalPresentationStyle = .fullScreen
present(viewController, animated: true, completion: nil)
4- 스토리 보드에서
세 구아를 선택하고 프레젠테이션을로 설정하십시오 FullScreen
.
5- 스위 즐링
extension UIViewController {
static func swizzlePresent() {
let orginalSelector = #selector(present(_: animated: completion:))
let swizzledSelector = #selector(swizzledPresent)
let orginalMethod = class_getInstanceMethod(self, orginalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
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 == .pageSheet
|| 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
어딘가에
위의 답변과 제안은 옳으며 아래는 다른 버전이며 프로그래밍 방식으로 효율적으로 사용하는 방법입니다.
# 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)
Objective-C에서 내가 찾은 두 가지 방법.
두 열거 형 modalPresentationStyles가 모두 0보다 작은 것을 알았습니다.
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,
UIModalPresentationPageSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
UIModalPresentationFormSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
UIModalPresentationCurrentContext API_AVAILABLE(ios(3.2)),
UIModalPresentationCustom API_AVAILABLE(ios(7.0)),
UIModalPresentationOverFullScreen API_AVAILABLE(ios(8.0)),
UIModalPresentationOverCurrentContext API_AVAILABLE(ios(8.0)),
UIModalPresentationPopover API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(tvos),
UIModalPresentationBlurOverFullScreen API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios) API_UNAVAILABLE(watchos),
UIModalPresentationNone API_AVAILABLE(ios(7.0)) = -1,
UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2,
};
- 기본 ViewController 메소드를 재정의하십시오 (제안)
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
if ([self isKindOfClass:[UINavigationController class]]) {
//default is UIModalPresentationPageSheet
viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
}
else if ([self isKindOfClass:[UITabBarController class]]) {
viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
}
else if (viewControllerToPresent.modalPresentationStyle < 0){
viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
}
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
- 분석법 교환 (권장하지 않음)
참고 URL : https://stackoverflow.com/questions/56435510/presenting-modal-in-ios-13-fullscreen
'Programing' 카테고리의 다른 글
LINQ의 IN 절 (0) | 2020.06.14 |
---|---|
프로그램을 중단하지 않고 파이썬에서 경고 발생 (0) | 2020.06.14 |
iPhone 시뮬레이터에 .ipa 파일을 설치하는 방법 (0) | 2020.06.14 |
Gson for Java를 사용한 JSON 구문 분석 (0) | 2020.06.14 |
ngRepeat 사용시 표시되는 결과 수 제한 (0) | 2020.06.14 |