總體方向兩點(diǎn):
- model下米间,present方式推出界面强品。
- push橫屏,帶tabbar屈糊、navigation的榛,且一個(gè)item下所有控制器對(duì)應(yīng)的只有一個(gè)根navigation。
接下來說說push方式強(qiáng)制旋轉(zhuǎn)橫屏?xí)r遇到的坑吧.....
遇到的問題描述:
- 橫著逻锐,豎屏切換到橫屏夫晌,是否“鎖定豎屏”,都會(huì)偶爾造成無法旋轉(zhuǎn)至橫屏昧诱,iOS8表現(xiàn)較明顯晓淀。
- 橫著或豎著,切換到橫屏盏档,掛起凶掰,再進(jìn)入橫屏,退出妆丘,再進(jìn)入橫屏锄俄,反復(fù)切換,偶爾會(huì)導(dǎo)致無法橫屏勺拣,返回上豎屏?xí)r奶赠,界面返回了,但橫屏無法返回药有。
- 橫豎屏來回切換毅戈,跳轉(zhuǎn)苹丸,iOS8下,橫屏控制器,豎屏控制器中init方法苇经,橫屏中viewWillDisapper赘理、viewWillApper,調(diào)用順序會(huì)亂,與iOS7扇单、9執(zhí)行的順序不一樣商模,個(gè)人感覺應(yīng)該是push強(qiáng)制橫屏或都是同一個(gè)navigation導(dǎo)致的原因吧。
小總結(jié)下:
由于該項(xiàng)目橫屏中有來回跳轉(zhuǎn)蜘澜,到處跳轉(zhuǎn)的施流,一個(gè)item下對(duì)應(yīng)的根控制下又只能是同一個(gè)navigation,分享模塊又是基于tabbar上的navigation推出的,分享模塊無回調(diào)鄙信,導(dǎo)致我瞻前顧后的瞪醋,一直盯著push方式到底是否可以強(qiáng)制旋轉(zhuǎn)屏幕........百般絞盡腦汁的研究
思來想去的,就參考了愛奇藝橫屏播放視頻的方式装诡,橫屏中的跳轉(zhuǎn)都先回到豎屏播放控制器中跳轉(zhuǎn)银受,相當(dāng)于橫屏中跳轉(zhuǎn)多了一層過渡控制器;豎屏返回鸦采,應(yīng)該是返回根控制器宾巍,所以,橫屏應(yīng)該是一個(gè)新的navigation,而分享都是在橫屏中處理的赖淤。而我這項(xiàng)目中蜀漆,分享的列表是在tabbar上的navigation加在windows上的,分享跳轉(zhuǎn)都是基于tabbar的navigation咱旱,故無法再新建navigation,否則會(huì)引發(fā)一系列問題确丢,比如無法跳轉(zhuǎn)至首頁,基本上各種在橫屏里面的老代碼跳轉(zhuǎn)方式都不行了吐限。
故此鲜侥,我又回到全部push方式繼續(xù)坑........
因?yàn)槲乙膊幌氚。绻胮resent方式涉及改動(dòng)的代碼模塊太多了.....
其實(shí)有點(diǎn)不明白的是诸典,產(chǎn)品為何如此設(shè)計(jì):橫屏和豎屏描函,全模塊之間的跳轉(zhuǎn),試問這樣真的好嗎.........
接下來分析下push方式狐粱,僅限于參考和積累問題吧:
解決方案:
先說下思路吧:
1.實(shí)時(shí)的更新當(dāng)前應(yīng)用所支持的方向舀寓,手動(dòng)調(diào)用方法- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
2.把當(dāng)前控制器的方向給到當(dāng)前navigation肌蜻,一定要保證統(tǒng)一互墓,不能亂套,否則會(huì)導(dǎo)致界面來回跳轉(zhuǎn)錯(cuò)亂的問題蒋搜;
3.及時(shí)刷新當(dāng)前控制器,手動(dòng)調(diào)用方法[UIViewController attemptRotationToDeviceOrientation]篡撵。
一判莉、 present方式:
就不多說了,調(diào)用系統(tǒng)的三個(gè)方法育谬,基本上沒什么問題券盅。
二、push方式:
基類tabbar代碼:
#pragma mark - - orientation
// 是否支持轉(zhuǎn)屏
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
// 返回nav棧中的最后一個(gè)對(duì)象支持的旋轉(zhuǎn)方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
// 返回nav棧中最后一個(gè)對(duì)象,堅(jiān)持旋轉(zhuǎn)的方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}-
基類navigation代碼:
//旋轉(zhuǎn)方向 默認(rèn)豎屏
@property (nonatomic , assign) UIInterfaceOrientation interfaceOrientation;
@property (nonatomic , assign) UIInterfaceOrientationMask interfaceOrientationMask;#pragma mark - - orientation //設(shè)置是否允許自動(dòng)旋轉(zhuǎn) - (BOOL)shouldAutorotate { return YES; } //設(shè)置支持的屏幕旋轉(zhuǎn)方向 - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return self.interfaceOrientationMask; } //設(shè)置presentation方式展示的屏幕方向 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return self.interfaceOrientation; }
基類BaseViewController代碼:
- (void)viewDidLoad
{
[super viewDidLoad];
[UIViewController attemptRotationToDeviceOrientation];
}-
AppDelegate代碼
@property (assign , nonatomic) BOOL isForceLandscape;
@property (assign , nonatomic) BOOL isForcePortrait;-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ if (self.isForceLandscape) { return UIInterfaceOrientationMaskLandscape; }else if (self.isForcePortrait){ return UIInterfaceOrientationMaskPortrait; } return UIInterfaceOrientationMaskPortrait; }
-
橫屏viewController代碼:
重點(diǎn)說明:
1.此處需要手動(dòng)調(diào)用
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window膛檀;
且設(shè)置當(dāng)前 應(yīng)用只支持橫屏锰镀;
因?yàn)椋摲椒ㄔ趘iewWillAppear之后執(zhí)行的宿刮。
2.更新了支持的方向后互站,記得刷新下控制器,調(diào)用:
[UIViewController attemptRotationToDeviceOrientation];
否則僵缺,[UIScreen mainScreen].bounds的size不是你期望的;self.view.frame/bounds都不是期望的踩叭。
3.其實(shí)網(wǎng)上說的一些普通的方式實(shí)現(xiàn)橫屏磕潮,問題多,更多的是因?yàn)閟elf.view.frame/bounds/[UIScreen mainScreen].bounds沒有及時(shí)更新的容贝。- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //強(qiáng)制旋轉(zhuǎn)豎屏 [self forceOrientationLandscape]; CKNavigationController *navi = (CKNavigationController *)self.navigationController; [self.navigationController setNavigationBarHidden:YES animated:animated]; navi.interfaceOrientation = UIInterfaceOrientationLandscapeRight; navi.interfaceOrientationMask = UIInterfaceOrientationMaskLandscapeRight; //強(qiáng)制翻轉(zhuǎn)屏幕自脯,Home鍵在右邊。 [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"]; //刷新 [UIViewController attemptRotationToDeviceOrientation]; }
重點(diǎn)說明:
1.離開橫屏?xí)r斤富、橫屏中跳轉(zhuǎn)膏潮,記得強(qiáng)制旋轉(zhuǎn)至豎屏;
2.如果沒有及時(shí)旋轉(zhuǎn)至橫屏满力,會(huì)導(dǎo)致[UIScreen mainScreen].bounds沒有及時(shí)更新焕参,從而影響其它模塊的布局問題;
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//強(qiáng)制旋轉(zhuǎn)豎屏
[self forceOrientationPortrait];
CKNavigationController *navi = (CKNavigationController *)self.navigationController;
navi.interfaceOrientation = UIInterfaceOrientationPortrait;
navi.interfaceOrientationMask = UIInterfaceOrientationMaskPortrait;
//設(shè)置屏幕的轉(zhuǎn)向?yàn)樨Q屏
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
//刷新
[UIViewController attemptRotationToDeviceOrientation];
}
#pragma mark 橫屏設(shè)置
//強(qiáng)制橫屏
- (void)forceOrientationLandscape
{
CKAppDelegate *appdelegate=(CKAppDelegate *)[UIApplication sharedApplication].delegate;
appdelegate.isForceLandscape=YES;
appdelegate.isForcePortrait=NO;
[appdelegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
}
//強(qiáng)制豎屏
- (void)forceOrientationPortrait
{
CKAppDelegate *appdelegate=(CKAppDelegate *)[UIApplication sharedApplication].delegate;
appdelegate.isForcePortrait=YES;
appdelegate.isForceLandscape=NO;
[appdelegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
}
- (BOOL)prefersStatusBarHidden{
return YES;
}
感受
-
網(wǎng)上找了很多種方法油额,關(guān)于
這個(gè)方法有人說上架可能會(huì)被拒叠纷,雖然是間接調(diào)用私有方法。
但這個(gè)方法經(jīng)過多輪測(cè)試潦嘶,其實(shí)不是有用的涩嚣,不靠譜,只要按照我上面說的步驟測(cè)試掂僵,絕對(duì)會(huì)有bug的航厚,故此不建議大家使用該方法。- (void)interfaceOrientation:(UIInterfaceOrientation)orientation{ if([[UIDevicecurrentDevice] respondsToSelector:@selector(setOrientation:)]) { SEL selector =NSSelectorFromString(@"setOrientation:"); NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIDevicecurrentDevice]]; intval = orientation; // 從2開始是因?yàn)? 1 兩個(gè)參數(shù)已經(jīng)被selector和target占用 [invocation setArgument:&val atIndex:2]; [invocation invoke]; }}
以上所述锰蓬,支持iOS7幔睬、8、9系統(tǒng)互妓,經(jīng)iphone \iPod測(cè)試過溪窒,但貌似iOS8從橫屏挑戰(zhàn)至其它豎屏的界面坤塞,偶爾會(huì)有問題,概率很小澈蚌,不影響摹芙。
原因:可能是iOS8 SDK與其它不同吧。
更新iOS8的問題:
iOS8-8.4宛瞄,橫屏跳轉(zhuǎn)至其它界面浮禾,最好延遲跳轉(zhuǎn),不然其它界面的viewWillApper會(huì)比橫屏的viewWillDisApper先執(zhí)行份汗,導(dǎo)致無法旋轉(zhuǎn)回來盈电。
CGFloat timef = 0.8;
//主要是轉(zhuǎn)屏之后view的再次旋轉(zhuǎn)
if (kSystemVersion>8||kSystemVersion<8.4) {
self.view.hidden = YES;
[self viewWillDisappear:NO];
timef = 0.1;
}
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, timef*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^(){
//跳轉(zhuǎn)界面
});
});