【iOS】Method Swizzling - 系统方法替换
2016-12-13 本文已影响151人
CoderHuangRui
需求
在使用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
完成