美文网首页
关于WKWebView播放视屏强制横屏的问题

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

作者: 点击就送屠龙宝刀 | 来源:发表于2020-07-15 11:12 被阅读0次

    首先说一下需求吧!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播放视屏强制横屏的问题

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