[iOS]UIViewController+Present

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

示意图:
未处理前

处理后:




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值