Inilah cara kami mencapainya dengan menggunakan metode swizzling:
Objektif-C
UIViewController + iOS13Fixes.h
#import <Foundation/Foundation.h>
@interface UIViewController (iOS13Fixes)
@end
UIViewController + iOS13Fixes.m
#import <objc/runtime.h>
@implementation UIViewController (iOS13Fixes)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(presentViewController:animated:completion:);
SEL swizzledSelector = @selector(swizzled_presentViewController:animated:completion:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL methodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (methodExists) {
method_exchangeImplementations(originalMethod, swizzledMethod);
} else {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
});
}
- (void)swizzled_presentViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated completion:(void (^)())completion {
if (@available(iOS 13.0, *)) {
if (viewController.modalPresentationStyle == UIModalPresentationAutomatic || viewController.modalPresentationStyle == UIModalPresentationPageSheet) {
viewController.modalPresentationStyle = UIModalPresentationFullScreen;
}
}
[self swizzled_presentViewController:viewController animated:animated completion:completion];
}
@end
Cepat
UIViewController + iOS13Fixes.swift
import UIKit
@objc public extension UIViewController {
private func swizzled_present(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) {
if #available(iOS 13.0, *) {
if viewControllerToPresent.modalPresentationStyle == .automatic || viewControllerToPresent.modalPresentationStyle == .pageSheet {
viewControllerToPresent.modalPresentationStyle = .fullScreen
}
}
self.swizzled_present(viewControllerToPresent, animated: animated, completion: completion)
}
@nonobjc private static let _swizzlePresentationStyle: Void = {
let instance: UIViewController = UIViewController()
let aClass: AnyClass! = object_getClass(instance)
let originalSelector = #selector(UIViewController.present(_:animated:completion:))
let swizzledSelector = #selector(UIViewController.swizzled_present(_:animated:completion:))
let originalMethod = class_getInstanceMethod(aClass, originalSelector)
let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)
if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
if !class_addMethod(aClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)) {
method_exchangeImplementations(originalMethod, swizzledMethod)
} else {
class_replaceMethod(aClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
}
}()
@objc static func swizzlePresentationStyle() {
_ = self._swizzlePresentationStyle
}
}
dan in AppDelegate
, application:didFinishLaunchingWithOptions:
aktifkan swizzling dengan memanggil (hanya versi swift):
UIViewController.swizzlePresentationStyle()
Pastikan hanya dipanggil sekali (gunakan dispatch_once
atau setara).
Lebih lanjut tentang metode swizzling di sini:
viewController.modalPresentationStyle
ke.pageSheet
dan memanggilself.swizzled_present(:,:,:)
. Mungkin tidak terlalu cantik, tetapi inti dari postingan ini didasarkan pada asumsi bahwa Anda sudah memiliki proyek yang luas dengan banyak panggilan untuk presentasi modal dan Anda ingin memulihkan perilaku pra-iOS13 tanpa memperbarui setiap baris kode.