ios 解决app整体需要禁止横屏,sdk或个别页面需要横屏

2019/7/22 17:56:43 人评论 次浏览 分类:学习教程

我遇到的问题是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好强大。

 

 

 

相关资讯

    暂无相关的资讯...

共有访客发表了评论 网友评论

验证码: 看不清楚?
    -->