美文网首页
【iOS】Method Swizzling - 系统方法替换

【iOS】Method Swizzling - 系统方法替换

作者: CoderHuangRui | 来源:发表于2016-12-13 11:21 被阅读151次

    需求
    在使用UIImagePickerController进行拍照时,如果没有相机权限,则需要弹出一个提示框提醒用户。

    实现方式
    1、每个弹出UIImagePickerController的地方写上弹框代码
    2、写个UIImagePickerController的子类,重写其父类方法
    3、使用Method Swizzling

    使用Method Swizzling来实现需求
    步骤
    1、给UIViewController添加一个Category,

    //
    //  UIViewController+UIImagePickerCamera.m
    //
    //  Created by 黄瑞 on 2016/11/24.
    //  Copyright © 2016年 黄瑞. All rights reserved.
    //
    
    #import "UIViewController+UIImagePickerCamera.h"
    
    @implementation UIViewController (UIImagePickerCamera)
    
    + (void)load {
        SEL orig_present = @selector(presentViewController:animated:completion:);
        SEL swiz_present = @selector(swiz_presentViewController:animated:completion:);
        [UIViewController swizzleMethods:[self class] originalSelector:orig_present swizzledSelector:swiz_present];
    }
    
    //exchange implementation of two methods
    
    + (void)swizzleMethods:(Class)class originalSelector:(SEL)origSel swizzledSelector:(SEL)swizSel {
        
        Method origMethod = class_getInstanceMethod(class, origSel);
        Method swizMethod = class_getInstanceMethod(class, swizSel);
        
        //class_addMethod will fail if original method already exists
        
        BOOL didAddMethod = class_addMethod(class, origSel, method_getImplementation(swizMethod), method_getTypeEncoding(swizMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class, swizSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        } else {
            //origMethod and swizMethod already exist
            method_exchangeImplementations(origMethod, swizMethod);
        }
    }
    
    - (void)swiz_presentViewController:(UIViewController *)vc animated:(BOOL)animated completion:(void(^)(void))completion {
        if ([vc isKindOfClass:[UIImagePickerController class]]) {
            UIImagePickerController *imgPicker = (UIImagePickerController *)vc;
            if (imgPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
                completion = ^{
                    completion();
                    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
                    if (status == AVAuthorizationStatusDenied || status == AVAuthorizationStatusRestricted) {
                        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"请在iPhone的“设置-隐私-相机”选项中,允许XX访问您的相机。" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil];
                        [alert show];
                    }
                };
            }
        }
        [self swiz_presentViewController:vc animated:animated completion:completion];
    }
    
    @end
    
    

    需要在.h文件中引入AVFoundation框架

    //
    //  UIViewController+UIImagePickerCamera.h
    //
    //  Created by 黄瑞 on 2016/11/24.
    //  Copyright © 2016年 黄瑞. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import <AVFoundation/AVFoundation.h>
    #import <objc/runtime.h>
    
    @interface UIViewController (UIImagePickerCamera)
    
    @end
    

    完成

    相关文章

      网友评论

          本文标题:【iOS】Method Swizzling - 系统方法替换

          本文链接:https://www.haomeiwen.com/subject/fqgvmttx.html