关于WKWebView播放视屏强制横屏的问题

首先说一下需求吧!app整体竖屏不支持旋转,只有在webview播放视屏的时候横屏(不是自动旋转哦)。刚开始拿到需求的时候以为很简单。但是由于项目之前其实已经有一部分这块的逻辑了,所以就想着捡现成的。网上百度了很多,思路上基本上都是调用系统监听打开全屏(UIWindowDidResignKeyNotification、UIWindowDidBecomeVisibleNotification)、退出全屏(UIWindowDidBecomeHiddenNotification)从这里开始有一点分支一个是调用系统那一套旋转方法

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window ;

- (BOOL)shouldAutorotate;

- (UIInterfaceOrientationMask)supportedInterfaceOrientations; 

-(UIInterfaceOrientation)bl_preferredInterfaceOrientationForPresentation;

一个是自己对window做旋转,也就是在相应的监听方法里调用旋转方法例如:

//将要进入全屏

UIApplication *application=[UIApplication sharedApplication];

[applicationsetStatusBarOrientation: UIInterfaceOrientationLandscapeRight];

application.keyWindow.transform=CGAffineTransformMakeRotation(M_PI/2);

CGRect frame = [UIScreen mainScreen].bounds;

application.keyWindow.bounds=CGRectMake(0,0, frame.size.height, frame.size.width);

//退出全屏

UIApplication *application=[UIApplication sharedApplication];

[applicationsetStatusBarOrientation: UIInterfaceOrientationLandscapeRight];

CGRect frame = [UIScreen mainScreen].bounds;

application.keyWindow.bounds=CGRectMake(0,0, frame.size.width, frame.size.height);

application.keyWindow.transform=CGAffineTransformMakeRotation(M_PI * 2);

先说一下这个思路吧  首先这个监听事件就不是那么准确,别的事件是有可能触发这个监听的。这样就会造成一些界面错乱的情况。

之后我就再想能不能让h5那边给一个事件告诉我全屏 和 退出全屏的时机。后来跟项目经理沟通后,感觉指望不上。

好吧,这条路走不通。打开播放视频的视图层级看了以后,发现了一个AVFullScreenViewController。度娘了以后知道这是一个苹果没有暴露给我们使用的视频类控制器。当时的想法是分类运用runtime,来对这个控制器做一些操作。结果发现拿不到这个控制器。真是尴尬。后来查到了贝聊科技的BLLandscape。这个思路就有点类似了。不过他是对UIViewcontroller进行的分类,关键在于怎么区分出AVFullScreenViewController。看了一下源码:

- (BOOL)checkSelfNeedLandscape{ NSProcessInfo *processInfo = [NSProcessInfo processInfo]; NSOperatingSystemVersion operatingSytemVersion = processInfo.operatingSystemVersion;if(operatingSytemVersion.majorVersion == 8) { NSString *className = NSStringFromClass(self.class);if([@[@"AVPlayerViewController", @"AVFullScreenViewController", @"AVFullScreenPlaybackControlsViewController"] containsObject:className]) {returnYES; }if([self isKindOfClass:[UIViewController class]] && [self childViewControllers].count && [self.childViewControllers.firstObject isKindOfClass:NSClassFromString(@"AVPlayerViewController")]) {returnYES; } }elseif(operatingSytemVersion.majorVersion == 9){ NSString *className = NSStringFromClass(self.class);if([@[@"WebFullScreenVideoRootViewController", @"AVPlayerViewController", @"AVFullScreenViewController"] containsObject:className]) {returnYES; }if([self isKindOfClass:[UIViewController class]] && [self childViewControllers].count && [self.childViewControllers.firstObject isKindOfClass:NSClassFromString(@"AVPlayerViewController")]) {returnYES; } }elseif(operatingSytemVersion.majorVersion == 10){if([self isKindOfClass:NSClassFromString(@"AVFullScreenViewController")]) {returnYES; } }returnNO;}

可能是系统版本的差异性吧,[self isKindOfClass:NSClassFromString(@"AVFullScreenViewController")]这段代码并没有用。直接上代码吧!

UIViewcontroller建一个分类:

#import "UIViewController+Landscape.h"

#import

@implementation UIViewController (Landscape)


+ (void)load{

    staticdispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{

        Classclass = [selfclass];

        SELoriginalSelector =@selector(viewWillAppear:);

        SELswizzledSelector =@selector(bl_viewWillAppear:);

        MethodoriginalMethod =class_getInstanceMethod(class, originalSelector);

        MethodswizzledMethod =class_getInstanceMethod(class, swizzledSelector);

        BOOLsuccess =class_addMethod(class, originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));

        if(success) {

            class_replaceMethod(class, swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));

        }else{

            method_exchangeImplementations(originalMethod, swizzledMethod);

        }

        SELoriginalSelector1 =@selector(viewWillDisappear:);

        SELswizzledSelector1 =@selector(bl_viewWillDisappear:);

        MethodoriginalMethod1 =class_getInstanceMethod(class, originalSelector1);

        MethodswizzledMethod1 =class_getInstanceMethod(class, swizzledSelector1);

        BOOLsuccess1 =class_addMethod(class, originalSelector1,method_getImplementation(swizzledMethod1),method_getTypeEncoding(swizzledMethod1));

        if(success1) {

            class_replaceMethod(class, swizzledSelector1,method_getImplementation(originalMethod1),method_getTypeEncoding(originalMethod1));

        }else{

            method_exchangeImplementations(originalMethod1, swizzledMethod1);

        }

    });

}

- (void)bl_viewWillAppear:(BOOL)animated{

    [selfbl_viewWillAppear:animated];

    if ([[[UIApplication sharedApplication].keyWindow.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"MPInlineVideoFullscreenViewController")] ||

    [[[UIApplication sharedApplication].keyWindow.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"AVFullScreenViewController")]){

        UIApplication *application=[UIApplication sharedApplication];

        application.keyWindow.transform=CGAffineTransformMakeRotation(M_PI/2);

        CGRect frame = [UIScreen mainScreen].bounds;

        application.keyWindow.bounds=CGRectMake(0,0, frame.size.height, frame.size.width);

    }

}

- (void)bl_viewWillDisappear:(BOOL)animated{

    [self bl_viewWillDisappear:animated];

    if ([[[UIApplication sharedApplication].keyWindow.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"MPInlineVideoFullscreenViewController")] ||

    [[[UIApplication sharedApplication].keyWindow.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"AVFullScreenViewController")]){

        UIApplication *application=[UIApplication sharedApplication];

        CGRect frame = [UIScreen mainScreen].bounds;

        application.keyWindow.bounds=CGRectMake(0,0, frame.size.width, frame.size.height);

        application.keyWindow.transform=CGAffineTransformMakeRotation(M_PI * 2);

    }

}

@end

本来准备用系统那一套旋转方法的,但是在不同系统上面不同表现。实在摸不清头脑,放弃了。如果有大佬知道原因的话望指点一二。第一次写,有什么问题,麻烦各位大佬指正!

你可能感兴趣的:(关于WKWebView播放视屏强制横屏的问题)