我遇到的问题是sdk中的,app整体需要禁止横屏,sdk内部的识别页需要横屏,所以有参考网上大神的代码,最后发现最好的解决方案是运行时-runtime
OCFTOCRRotation.h
----------------------------------------------------
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface OCFTOCRRotation : NSObject
/**
交换 系统方法和自定义的方法的实现
@param oldSEL 系统方法
@param newSEL 自己方法,交换的方法
*/
-(void)hookMehod:(SEL)oldSEL andNew:(SEL)newSEL;
/**
交换方法-让系统方法指向系统,自己的方法指向自己
*/
- (void)recover;
@end
NS_ASSUME_NONNULL_END
OCFTOCRRotation.m
---------------------------------------------
#import "OCFTOCRRotation.h"
#import <objc/runtime.h>
#import <UIKit/UIKit.h>
@implementation OCFTOCRRotation
////方法:
-(void)hookMehod:(SEL)oldSEL andNew:(SEL)newSEL {
Class oldClass = objc_getClass([@"AppDelegate" UTF8String]);
Class newClass = [self class];
id delegate = [UIApplication sharedApplication].delegate;
SEL selector = NSSelectorFromString(@"application:supportedInterfaceOrientationsForWindow:");
if ([delegate respondsToSelector:selector]) {
NSLog(@"respondsToSelector=YES");
//在AppDelegatez中添加newSEL
class_addMethod(oldClass, newSEL, class_getMethodImplementation(newClass, newSEL), nil);
//在原来class中获得原来的方法
Method oldMethod = class_getInstanceMethod(oldClass, oldSEL);
assert(oldMethod);
//在原来class中获得新加的方法
Method newMethod = class_getInstanceMethod(oldClass, newSEL);
assert(newMethod);
//j交换两个方法的实现
method_exchangeImplementations(oldMethod, newMethod);
}else{
NSLog(@"AppDelegate未实现application:supportedInterfaceOrientationsForWindow:");
//此处强制添加实现的方法
}
}
- (void)recover{
Class oldClass = objc_getClass([@"AppDelegate" UTF8String]);
SEL selector = NSSelectorFromString(@"application:supportedInterfaceOrientationsForWindow:");
Method newMethod = class_getInstanceMethod(oldClass, @selector(SDKApplication:supportedInterfaceOrientationsForWindow:));
assert(newMethod);
Method oldMethod = class_getInstanceMethod(oldClass, selector);
assert(oldMethod);
method_exchangeImplementations(newMethod, oldMethod);
}
-(UIInterfaceOrientationMask)SDKApplication:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSLog(@"SDKDelegatesetAllowRotation");
return UIInterfaceOrientationMaskAll;
}
完整的代码就是上面了,主要思路就是,我在自定义类中,自定义个方法返回允许app横屏UIInterfaceOrientationMaskAll,然后把这个方法使用运行时加到AppDelegate中,在使用method_exchangeImplementations交换两个方法的IMP指针。method_exchangeImplementations作用:method_exchangeImplementations可以交换两个方法的具体实现。
同理另一个方法的主要是用来恢复系统方法的实现。
下面就是怎么实现了,我的实现是在调转识别页的代码处添加-(void)hookMehod:(SEL)oldSEL andNew:(SEL)newSEL;交换方法实现,在页面回到上个页面,也就是pop或者dismiss页面的时候,再把两个方法的实现交换回来,这样就不影响整个页面的旋转策略。最后的感受就是果然runtime好强大。