[iOS]UIViewController+Present

mac2025-10-22  6

Demo:https://download.csdn.net/download/u012881779/11950564 UIViewController+Present这个分类,用来适配iOS13之后UIViewController模态弹出问题. 使用这种方式就不用去项目中挨个找写模态弹出的地方.

- (IBAction)tapButtonAction:(id)sender { UIButton *tempBut = (UIButton *)sender; if (tempBut.tag == 1000) { HomeViewController *home = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil]; [self presentViewController:home animated:YES completion:nil]; } else if (tempBut.tag == 1001) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"提示内容" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]; [alert addAction:sureAction]; [self presentViewController:alert animated:YES completion:nil]; } }

UIViewController+Present

#import <UIKit/UIKit.h> @interface UIViewController (Present) // category中不能添加属性,所以使用运行时的方式处理 @property (nonatomic, assign) BOOL GA_automaticallySetModalPresentationStyle; @end #import "UIViewController+Present.h" #import <objc/runtime.h> static const char *GA_automaticallySetModalPresentationStyleKey; @implementation UIViewController (Present) + (void)load { /* * OBJC_EXPORT Method _Nullable class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) * 返回给定类的指定实例方法。 * @param cls 您要检查的类。 * @param name 您要检索的方法的选择器。 * @return 对应于由指定的选择器的实现的方法 * 由\e cls指定的类的\e name, 或者\c NULL 如果指定的类或其名称 * 超类不包含具有指定选择器的实例方法。 * @note 该函数在超类中搜索实现,而\ c class_copyMethodList则不。 */ Method originAddObserverMethod = class_getInstanceMethod(self, @selector(presentViewController:animated:completion:)); Method swizzledAddObserverMethod = class_getInstanceMethod(self, @selector(GA_presentViewController:animated:completion:)); /* * OBJC_EXPORT void method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) * 交换两种方法的实现。 * @param m1方法 与第二种方法交换。 * @param m2方法 与第一种方法交换。 * @note 这是以下内容的原子版本: * \ code * IMP IMP1 = method_getImplementation(M1); * IMP imp2 = method_getImplementation(m2); * method_setImplementation(m1,imp2); * method_setImplementation(m2,imp1); * \ endcode */ method_exchangeImplementations(originAddObserverMethod, swizzledAddObserverMethod); } // 设置GA_automaticallySetModalPresentationStyle - (void)setGA_automaticallySetModalPresentationStyle:(BOOL)GA_automaticallySetModalPresentationStyle { objc_setAssociatedObject(self, GA_automaticallySetModalPresentationStyleKey, @(GA_automaticallySetModalPresentationStyle), OBJC_ASSOCIATION_ASSIGN); } // 获取GA_automaticallySetModalPresentationStyle - (BOOL)GA_automaticallySetModalPresentationStyle { id obj = objc_getAssociatedObject(self, GA_automaticallySetModalPresentationStyleKey); if (obj) { return [obj boolValue]; } return [self GA_judgeAutoSetModalPresentationStyle]; } // 判断是否需要自动设置模式显示样式 并不是所有继承于UIViewController的类都要处理 - (BOOL)GA_judgeAutoSetModalPresentationStyle { if ([self isKindOfClass:[UIImagePickerController class]] || [self isKindOfClass:[UIAlertController class]]) { // 测试了一下UIAlertController不限制也没毛病,当然限制也没问题。 return NO; } return YES; } // 用于替换presentViewController:animated:completion:的新方法 - (void)GA_presentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^)(void))completion { if (@available(iOS 13.0, *)) { if (viewController.GA_automaticallySetModalPresentationStyle) { viewController.modalPresentationStyle = UIModalPresentationFullScreen; viewController.modalInPresentation = YES; } [self GA_presentViewController:viewController animated:animated completion:completion]; } else { // Fallback on earlier versions [self GA_presentViewController:viewController animated:animated completion:completion]; } } @end

示意图: 未处理前 处理后:

 

最新回复(0)