iOS 全局禁止横屏后UIWebView全屏横屏播放视频如何解决

作者:简简单单 2015-07-15

UIWebView是iOS sdk中一个最常用的控件。是内置的浏览器控件,我们可以用它来浏览网页、打开文档等等。这篇文章我将使用这个控件,做一个简易的浏览器。UIWebview在播放网页视频的时候我们需要进行是否全屏状态的监听。

一般的需求是在播放视频时候需要横屏,退出全屏的时候不能横屏,但是UIWebview没有给出响应的方法,

Demo工程https://github.com/darren90/iOS_Demo/tree/master/02-UIWebview

1:其他界面不支持横屏:

这个比较容易我的思路是
在APPDelegate.h文件中增加属性:是否支持横屏

/***  是否允许横屏的标记 */
@property (nonatomic,assign)BOOL allowRotation;

在APPDelegate.m文件中增加方法,控制全部不支持横屏

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (self.allowRotation) {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

这样在其他界面想要横屏的时候,我们只要控制allowRotation这个属性就可以控制其他界面进行横屏了。

//需在上面#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.allowRotation = YES;
//不让横屏的时候 appDelegate.allowRotation = NO;即可

2:播放界面横屏:

2.1:播放界面横屏:网上的解决方案

网上有人给出两种方法:

第一:但是iOS8下失效,没有用
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(videoStarted:)name:@"UIMoviePlayerControllerDidEnterFullscreenNotification"object:nil];//

第二:通过js,但是没有找到详细的,可解决的方案。

所以也就是没有找到成熟的方案,所以就自己分析了。

2.2:播放界面横屏:问题分析

方法总会有的,我们要向监听UIWebView视频播放时候是否全屏,也就是我们要能拿到播放视频的view或者是viewcontroller,但是由于UIWebView没有比较直观的方法,所以只能从其他地方下手了

通过Reveal我们可以查看到view的一些层级关系,可以看出弹出播放的是AVPlayerView,在UIWindow上,



好了,问题到这已经很明晰了,我们要么能拿到AVPlayerView,要呢拿到UIWindow才能控制播放界面,分析后发现AVPlayerView不好拿,但是UIWindow及很easy了。

2.3:播放界面横屏:问题解决

所以这里可以使用UIWindow的通知,就可以解决

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(begainFullScreen) name:UIWindowDidBecomeVisibleNotification object:nil];//进入全屏
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endFullScreen) name:UIWindowDidBecomeHiddenNotification object:nil];//退出全屏

在退出全屏时,增加逻辑让其强制编程竖屏,这样当全屏播放的时候,点击down("完成")时,就会自动变成竖屏了。

// 进入全屏
-(void)begainFullScreen
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = YES;
}
// 退出全屏
-(void)endFullScreen
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = NO;
    
    //强制归正:
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val =UIInterfaceOrientationPortrait;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}




iOS UIWebView 全屏播放视频需横屏但是app不支持横屏的解决办法

 在使用UIWebView播放视频的时候,想到视频应该能够旋转播放。但是app本身是不支持旋转的,所以把代码记录如下,引申出来的答案就是:所有的你想要进行页面自动旋转的页面都是可以用这种方法。不说太多的废话,代码如下:

首先在appDelegate中进行代理的设置,这个方法系统在屏幕旋转等的时候会自动调用,不用太多的担心调用时机:

//为视频的旋转做准备的

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

if(_isFull)

returnUIInterfaceOrientationMaskAll;

returnUIInterfaceOrientationMaskPortrait;

}

上面的代码为:设置一个app的全局变量_isFull,在需要屏幕旋转的地方把全局变量进行改变并发送相应的通知(通知在下面),会自动调用上面的方法进行屏幕的旋转。

.h代码如下:

@interface AppDelegate :UIResponder

{

BOOL _isFull; // 是否全屏

}

@property (nonatomic)BOOL isFull;

上面已经将需要的变换代码设置好了,下面要做的就是使用通知在需要旋转屏幕的时候系统自动调用上面的代码:

[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(videoStarted:)name:@"UIMoviePlayerControllerDidEnterFullscreenNotification"object:nil];// 播放器即将播放通知

[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(videoFinished:)name:@"UIMoviePlayerControllerDidExitFullscreenNotification"object:nil];// 播放器即将退出通知

上面发送了两个通知,分别为:UIMoviePlayerControllerDidEnterFullscreenNotification,UIMoviePlayerControllerWillExitFullscreenNotification,我使用的是这两个方法,有的网上说使用UIMoviePlayerControllerDidExitFullscreenNotification这个通知,但是我使用之后发现不行,应该使用WillExit这个通知。通知之后的代码如下:

上面的方法执行完毕之后,会系统调用一开始在appDelegate里面写的方法,从而通过改变isFull的参数进行屏幕支持方向的改变。

#pragma mark 调用视频的通知方法


#pragma mark 调用视频的通知方法

- (void)videoStarted:(NSNotification *)notification {// 开始播放

AppDelegate * appDelegate = [[UIApplication sharedApplication] delegate];

appDelegate.isFull = YES;

}


- (void)videoFinished:(NSNotification *)notification {//完成播放

AppDelegate *appDelegate = [[UIApplicationsharedApplication] delegate];

appDelegate.isFull =NO;

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {

SEL selector = NSSelectorFromString(@"setOrientation:");

NSInvocation *invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];

[invocationsetSelector:selector];

[invocationsetTarget:[UIDevicecurrentDevice]];

int val =UIInterfaceOrientationPortrait;

[invocationsetArgument:&val atIndex:2];

[invocationinvoke];

}

// NSLog(@"videoFinished %@", self.view.window.rootViewController.view);

//

// NSLog(@"a == %f", self.view.window.rootViewController.view.transform.a);

// NSLog(@"b == %f", self.view.window.rootViewController.view.transform.b);

// NSLog(@"c == %f", self.view.window.rootViewController.view.transform.c);

// NSLog(@"d == %f", self.view.window.rootViewController.view.transform.d);

// if (self.view.window.rootViewController.view.transform.c == 1 || self.view.window.rootViewController.view.transform.c == -1 ) {

// CGAffineTransform transform;

// //设置旋转度数

// // transform = CGAffineTransformRotate(self.view.window.rootViewController.view.transform, M_PI / 2);

// transform = CGAffineTransformIdentity;

// [UIView beginAnimations:@"rotate" context:nil ];

// [UIView setAnimationDuration:0.1];

// [UIView setAnimationDelegate:self];

// [self.view.window.rootViewController.view setTransform:transform];

// [UIView commitAnimations];

//

// self.view.window.rootViewController.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height );

// }

//

// [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];

}

相关文章

精彩推荐