GitHub傳送門ios
iOS13默認的presentViewController樣式git
這種樣式顯然不能符合咱們UI的要求,產生這樣的問題是由於咱們以前一直忽略了UIModalPresentationStyle這個屬性。github
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,
};
@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyle API_AVAILABLE(ios(3.2));
複製代碼
在iOS13以前的版本中, UIViewController的UIModalPresentationStyle屬性默認是UIModalPresentationFullScreen,而在iOS13中變成了UIModalPresentationPageSheet。 因此咱們須要在presentViewController時,設置一下UIModalPresentationStyle,就能夠達到舊的效果。bash
UIViewController *viewController = [[UIViewController alloc] init];
viewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self persentViewController:viewController animated:YES completion:nil];
複製代碼
若是在每一處presentViewController都設置modalPresentationStyle,顯然這不夠Cool。因此就有下面的思路。ui
在項目中建立UIViewController的Category,而且在.m中寫入以下部分atom
#import "UIViewController+LL_Utils.h"
#import <objc/runtime.h>
@implementation UIViewController (Utils)
+ (void)load {
Method originAddObserverMethod = class_getInstanceMethod(self, @selector(presentViewController:animated:completion:));
Method swizzledAddObserverMethod = class_getInstanceMethod(self, @selector(LL_presentViewController:animated:completion:));
method_exchangeImplementations(originAddObserverMethod, swizzledAddObserverMethod);
}
- (void)LL_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if (@available(iOS 13.0, *)) {
viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
[self LL_presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
// Fallback on earlier versions
[self LL_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
@end
複製代碼
到這裏已經能夠實現舊的PresentViewController的樣式,可是不能處理某個或者某類UIViewController避免自動設置modalPresentationStyle,因此就有了下面這個方案。spa
UIViewController+LL_Utils.hcode
@interface UIViewController (LL_Utils)
/**
Whether or not to set ModelPresentationStyle automatically for instance, Default is [Class LL_automaticallySetModalPresentationStyle].
@return BOOL
*/
@property (nonatomic, assign) BOOL LL_automaticallySetModalPresentationStyle;
/**
Whether or not to set ModelPresentationStyle automatically, Default is YES, but UIImagePickerController/UIAlertController is NO.
@return BOOL
*/
+ (BOOL)LL_automaticallySetModalPresentationStyle;
@end
複製代碼
UIViewController+LL_Utils.morm
#import "UIViewController+LL_Utils.h"
#import <objc/runtime.h>
static const char *LL_automaticallySetModalPresentationStyleKey;
@implementation UIViewController (LL_Utils)
+ (void)load {
Method originAddObserverMethod = class_getInstanceMethod(self, @selector(presentViewController:animated:completion:));
Method swizzledAddObserverMethod = class_getInstanceMethod(self, @selector(LL_presentViewController:animated:completion:));
method_exchangeImplementations(originAddObserverMethod, swizzledAddObserverMethod);
}
- (void)setLL_automaticallySetModalPresentationStyle:(BOOL)LL_automaticallySetModalPresentationStyle {
objc_setAssociatedObject(self, LL_automaticallySetModalPresentationStyleKey, @(LL_automaticallySetModalPresentationStyle), OBJC_ASSOCIATION_ASSIGN);
}
- (BOOL)LL_automaticallySetModalPresentationStyle {
id obj = objc_getAssociatedObject(self, LL_automaticallySetModalPresentationStyleKey);
if (obj) {
return [obj boolValue];
}
return [self.class LL_automaticallySetModalPresentationStyle];
}
+ (BOOL)LL_automaticallySetModalPresentationStyle {
if ([self isKindOfClass:[UIImagePickerController class]] || [self isKindOfClass:[UIAlertController class]]) {
return NO;
}
return YES;
}
- (void)LL_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if (@available(iOS 13.0, *)) {
if (viewControllerToPresent.LL_automaticallySetModalPresentationStyle) {
viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
}
[self LL_presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
// Fallback on earlier versions
[self LL_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
@end
複製代碼
固然還有一個更簡單的方法,直接下載UIViewController+LLUtils而且拖入到項目中,就能夠了。cdn