在項目過程中,有視頻橫豎屏切換的邏輯,但是在各種嘗試之后,個人感覺,在關(guān)閉掉app在當(dāng)前頁面橫豎屏支持,處理起來邏輯最簡單,但是我們又不能不支持用戶自己橫豎手機(jī)時候的動態(tài)支持,所以,我在自己的項目中通過監(jiān)聽設(shè)備信息來處理橫豎屏邏輯(可以簡單的避免有些用戶進(jìn)入到我們支持自動旋轉(zhuǎn)屏幕頁面的時候,當(dāng)時的設(shè)備就是橫屏的時候的一些問題,我們之間避開了)
個人實現(xiàn)邏輯如下:
1.進(jìn)入播放器頁面 確定當(dāng)前設(shè)備狀態(tài)及未進(jìn)行橫豎屏?xí)r 播放器視圖的位置及視圖關(guān)系
2.用戶點擊橫屏/豎屏,或者用戶手動旋轉(zhuǎn)的時候,進(jìn)行邏輯處理,將播放器從之前的父視圖移動到window上,然后將播放器旋轉(zhuǎn)正負(fù)90度(左橫屏和右橫屏,其實此時frame會變,寬高顛倒),然后調(diào)整播放器的frame為全屏), 反之,將播放器從window恢復(fù)到原父視圖(旋轉(zhuǎn)回復(fù)到0),然后修改frame即可
具體細(xì)節(jié)如下:
1.在進(jìn)入播放器頁面的時候,首先獲取當(dāng)前設(shè)備的狀態(tài),左橫屏?右橫屏?豎屏?代碼如下:
//以后還需要監(jiān)聽屏幕旋轉(zhuǎn) 和進(jìn)入后臺等操作
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doRotateAction:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppDidEnterBackGround:) name:UIApplicationDidEnterBackgroundNotification object:nil];
UIInterfaceOrientation sataus=[UIApplication sharedApplication].statusBarOrientation;
if (sataus == UIDeviceOrientationLandscapeLeft) {
self.currentOrientation = UIDeviceOrientationLandscapeLeft;
}else if (sataus == UIDeviceOrientationLandscapeRight){
self.currentOrientation = UIDeviceOrientationLandscapeRight;
}else{
self.currentOrientation = UIDeviceOrientationPortrait;
}
2.然后構(gòu)造播放器和視圖,效果如圖:
3.然后監(jiān)聽設(shè)備狀態(tài):
代碼如下:
//實現(xiàn)監(jiān)聽的通知方法:
- (void)doRotateAction:(NSNotification *)notification {
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
self.currentOrientation = UIDeviceOrientationPortrait;
if (isfullScreen) {
[self changeScreenFullScreen:NO];
}
} else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) {
if (self.currentOrientation == UIDeviceOrientationLandscapeLeft && isfullScreen ) {
return;
}
self.currentOrientation = UIDeviceOrientationLandscapeLeft;
[self changeScreenFullScreen:YES];
}else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight){
if (self.currentOrientation == UIDeviceOrientationLandscapeRight && isfullScreen ) {
return;
}
self.currentOrientation = UIDeviceOrientationLandscapeRight;
[self changeScreenFullScreen:YES];
}
}
- 關(guān)鍵的處理橫豎屏的代碼
//是否全屏
- (void)changeScreenFullScreen:(BOOL)fullScreen{
// if (!self.needDealTransForm) {
// NSLog(@"當(dāng)前代碼不允許橫豎屏 根據(jù)個人的邏輯來處理");
// return;
// }
[UIView animateWithDuration:0.3 animations:^{
if (fullScreen) {
//是全屏
[[UIApplication sharedApplication]setStatusBarHidden:YES];
[self removeFromSuperview];
UIWindow *window = [self mainWindow];
topView.hidden = NO ;
[window addSubview:self];
if (self.currentOrientation == UIDeviceOrientationLandscapeLeft) {
self.transform =CGAffineTransformMakeRotation(M_PI_2);
}else if (self.currentOrientation == UIDeviceOrientationLandscapeRight){
self.transform =CGAffineTransformMakeRotation(-M_PI_2);
}else{
self.transform =CGAffineTransformMakeRotation(M_PI_2);
}
self.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
bottomView.frame = CGRectMake(0, ScreenWidth-40, ScreenHeight, 40);
topView.frame = CGRectMake(0, 0, ScreenHeight, 40);
isfullScreen = YES;
[changeFullScreenBtn setImage:[UIImage imageNamed:@"ox"] forState:UIControlStateNormal];
return;
}else{
[[UIApplication sharedApplication]setStatusBarHidden:NO];
self.transform =CGAffineTransformMakeRotation(0);
self.frame = originFrame;
bottomView.frame = CGRectMake(0, self.frame.size.height-40, ScreenWidth, 40);
topView.hidden = YES;
[self removeFromSuperview];
[changeFullScreenBtn setImage:[UIImage imageNamed:@"dk"] forState:UIControlStateNormal];
[_parentView addSubview:self];
isfullScreen = NO;
}
}];
}
以上,基本上播放器橫豎屏功能已經(jīng)實現(xiàn),上面可能會有同學(xué)告訴我,為什么我既用frame,還用masonry,其實,我使用frame我沒辦法,當(dāng)我使用masonry設(shè)置播放器代理里面的bottomeView和topView的時候 ,旋轉(zhuǎn)的時候, 在iOS 11上效果是我們期望的效果,但是在iOS其他版本(個人試了iOS 10 和iOS 8)效果不是我們期望的那樣,后來也沒想明白,如果有朋友或者同學(xué)了解具體原因,可以給我指導(dǎo)一下,謝謝大家!
順便給大家上個demo: https://github.com/yangfangkuo/VideoOrientationTransform