向曾經的前輩致敬!
本人iOS開發(fā)界菜鳥一枚,技術有限,寫得不好還請大神指教,謝謝!
方式1:工程設置里勾選橫屏方向的旋轉
核心方法:
//是否支持旋轉
- (BOOL)shouldAutorotate { }
//支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { }
//presentation方式展示支持的方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { }
PS:以上方法只有控制器為Window的root控制器的時候才有效果
主流結構的解決方案:
現(xiàn)在主流的項目結構都是:UITabBarController+UINavigationController+UIViewController,這種結構Window的root控制器就是UITabBarController,這個時候我們就需要去獲取當前展示的控制器的這三個方法的返回值了,做法就是自定義3個控制器,分別繼承自UITabBarController,UINavigationController,UIViewController
在自定義繼承UITabBarController的.m文件里重寫
- (BOOL)shouldAutorotate { return [self.selectedViewController shouldAutorotate]; }
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return [self.selectedViewController supportedInterfaceOrientations]; }
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [self.selectedViewController preferredInterfaceOrientationForPresentation]; }
在自定義繼承UINavigationController的.m文件里重寫
- (BOOL)shouldAutorotate { return [self.topViewController shouldAutorotate]; }
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; }
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [self.topViewController preferredInterfaceOrientationForPresentation]; }
在自定義繼承UIViewController的.m文件里重寫
- (BOOL)shouldAutorotate { return NO; }
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; }
PS:讓項目中不支持旋轉的頁面全部繼承你自定義的UIViewController就可以了
優(yōu)勢:
設備在沒有鎖定旋轉的情況下,你的APP會根據(jù)設備的旋轉自動重新布局UI,一般在開發(fā)iPad程序中比較常見
劣勢:
- 1.大部分手機APP(游戲除外)一般都是只支持豎屏,只有個別頁面支持旋轉(大多為視頻類APP),所以每個頁面你都需要去手動控制是否支持旋轉
- 2.作為視頻類APP切換到全屏播放時候跟半屏的時候肯定UI控件的展示個數(shù)或者布局一般都會變化,這個時候你就需要封裝的播放器能準確的跟控制器同步,不然就會出現(xiàn)UI展示異常等情況
- 3.播放器需要跟控制器進行交互才能做到例如鎖定旋轉,設備鎖定旋轉情況下手動全屏等功能
方式2:通過UIView的transform實現(xiàn)全屏播放
核心方法:
- 1.監(jiān)聽設備的旋轉通知和獲取設備當前的朝向
// 監(jiān)聽設備旋轉通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
//必須調用此方法后元暴,下面的方法才有效,不然獲取到的結果一直為0 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
//獲取設備的朝向 [[UIDevice currentDevice] orientation]
- 2.根據(jù)獲取到的設備朝向來計算旋轉角度和狀態(tài)欄方向
//設置狀態(tài)欄方向(先將上面獲取到的設備朝向轉換為對應的狀態(tài)欄方向)
[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO];
//根據(jù)狀態(tài)欄方向獲取旋轉角度
- (CGAffineTransform)getTransformWithOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait) {
return CGAffineTransformIdentity;
} else if (orientation == UIInterfaceOrientationLandscapeLeft){
return CGAffineTransformMakeRotation(-M_PI_2);
} else if (orientation == UIInterfaceOrientationLandscapeRight){
return CGAffineTransformMakeRotation(M_PI_2);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
return CGAffineTransformMakeRotation(M_PI);
}
return CGAffineTransformIdentity;
}
***
#####關于狀態(tài)欄隱藏后再顯示UINavigationBar會出現(xiàn)上移的解決方案
當播放器切換全屏的時候通常會隱藏狀態(tài)欄,如果此時播放器所處的控制器的UINavigationBar也是展示狀態(tài),就會出現(xiàn)切換回半屏的時候UINavigationBar上移跟狀態(tài)欄重疊的情況,如圖:
![image.png](http://upload-images.jianshu.io/upload_images/2186218-fe4f6a40fae267fe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
>**普通青年的隱藏方式**
[[UIApplication sharedApplication] setStatusBarHidden:YES];
**文藝青年的隱藏方式**
//獲取到狀態(tài)欄
UIView *statusBar = [[UIApplication sharedApplication]valueForKey:@"statusBar"]
//設置透明度為0
statusBar.alpha = 0.0f;
***
###優(yōu)勢:
- 1.整個項目都不再支持屏幕旋轉了,媽媽再也不用擔心因為旋轉造成的UI布局困擾了
- 2.封裝播放器在也不需要跟控制器做交互,哥哥想什么時候轉就什么時候轉
- 3.半屏切全屏的旋轉動畫也好看多了,請參照(** *騰訊視頻* **)
###劣勢:
- 1.需要自己控制狀態(tài)欄的方向,當然如果你們的項目不介意全屏播放時微信通知顯示在左側或者右側,你也可以無視,例如(** *網易云音樂 * **)
***
##總結:
最開始在著手做視頻類項目之前,本人在網上也找了很多視頻類的demo,不過demo始終是demo,基本都是以實現(xiàn)功能為目的,很多細節(jié)和實際需求完全沒有考慮到的,最終的結果就是只能一邊借鑒一邊摸索,上面的2種方法就是通過借鑒和摸索慢慢整理出來的,希望能給初次著手此類需求的同學作為參考.目前手頭上的項目已經迭代了好幾個版本了,播放器也重寫了不下5次了,項目早期使用的是方式1,后來隨著功能越來越多(當然有些需求比較奇葩),暴露出來的問題也越來越多,最后換成了現(xiàn)在的方式2,到目前為止,我個人認為方式2的效果要優(yōu)于方式一,當然此結論僅供參考!