背景: 項目作為SDK接入到游戲項目中肢扯,切游戲是橫屏妒茬,SDK只支持豎屏,在xCode11上編譯包會出現(xiàn)一個瞬間的抖動問題
如何支持橫豎屏切換
- navigation中實現(xiàn):
//// For ios6, use supportedInterfaceOrientations & shouldAutorotate instead
- (UIInterfaceOrientationMask) supportedInterfaceOrientations{
return [self.viewControllers.lastObject supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}
- (BOOL) shouldAutorotate {
return [self.viewControllers.lastObject shouldAutorotate];
}
- ViewController中實現(xiàn):
//// For ios6, use supportedInterfaceOrientations & shouldAutorotate instead
- (UIInterfaceOrientationMask) supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
- (BOOL) shouldAutorotate {
return YES; //這里一定要是yes 如果是NO 就不支持自動切換蔚晨,也不會繼續(xù)調(diào)用另外兩個方法了
}
--- 以上對xcode10及以前模擬器都沒問題 ---
那么 xCode11 iOS 13 針對modalStyle推出了新特性乍钻,presentViewController的時候需要強制添加fullScreen的modalStyle,就會導致在橫屏切換到豎屏的過程中出現(xiàn)一個詭異的抖動铭腕,那么問題來了银择,fullScreen到底做了什么,和之前的present 有和區(qū)別呢
A->B 的情況下累舷,用fullScreen的話 會調(diào)用presentedViewController的viewlayoutsubviews導致重新布局 有一個切換 閃一下
這里有兩個方案
方案一
fullScreen模式下 在頁面A里攔截一下這種情況下 攔截一下頁面
方案二
使用overFullScreen 模式浩考,但這個模式在橫豎屏下會引發(fā)一系列連鎖反應,系統(tǒng)不會幫你強制豎屏被盈,當你presentingViewcontroller里實現(xiàn)了
- (BOOL) shouldAutorotate {
return YES;
}
相關(guān)代理之后析孽,他能夠根據(jù)當前window來實現(xiàn)頁面的橫豎屏轉(zhuǎn)換,到這里 只怎,如果你的需求已經(jīng)滿足了袜瞬,那么恭喜你,你已經(jīng)成功了身堡。下面內(nèi)容可以忽略了~
因為用到了鍵盤和UIMenuController邓尤,而這兩個東西并不在當前 application的keywindow上,下面可以看到,而我們要用到的鍵盤和Menu其實都是依附于UITextEffectsWindow上的
當我們使用overFullScreent的style汞扎,橫屏進入頁面的時候季稳,系統(tǒng)其實并不會將 UITextEffectsWindow 這個window自動旋轉(zhuǎn)為豎屏,系統(tǒng)判定當前仍然是橫屏澈魄,name鍵盤和menu仍然是按照橫屏的高度去計算的景鼠,這就會有問題,針對這種case一忱,目前用了一個比較迂回(一個坑一個坑去填)的解決辦法。
- 在present的時機 調(diào)用豎屏:
- (void)rotationToDeviceOrientation {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:@selector(setOrientation:)]];
invocation.selector = NSSelectorFromString(@"setOrientation:");
invocation.target = [UIDevice currentDevice];
int initOrientation = UIDeviceOrientationPortrait; // 這里我們需要傳的值是設(shè)備方向值
[invocation setArgument:&initOrientation atIndex:2];
[invocation invoke];
/** 下面代碼是為了當前導航欄旋轉(zhuǎn)至設(shè)備方向*/
[CCBaseNavigationController attemptRotationToDeviceOrientation];
}
- 處理鍵盤 或 Menu 在橫屏presentVC的時候谭确,顯示問題帘营,這里會有一個小特點,就是當APP從后臺切換會前臺之后逐哈,會觸發(fā)系統(tǒng)的刷新芬迄,這個時候能夠刷新,所以我們這里處理的就是這個極端case的UI顛倒顯示的問題
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(adjustKeyboardWindow) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
/*
這是一處及其惡心的代碼昂秃,為了適配iOS13橫豎屏切換的問題禀梳,
iOS13上用 overfullScreen present的VC,進入頁面
UITextEffectsWindow window不會切換豎屏肠骆,所以這里需要暴力扭轉(zhuǎn)一下
心虛的說一下 不知道會有啥坑 見招拆招吧~
**/
- (void)adjustKeyboardWindow {
if (@available(iOS 13.0, *)) {
NSUInteger windowCount = [[[UIApplication sharedApplication] windows] count];
if(windowCount < 2) {
return;
}
UIWindow *keyboardWindow = nil;
if(windowCount >= 2)//ios9以上算途,UIRemoteKeyboardWindow
{
keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
}
if (keyboardWindow.wind_width > keyboardWindow.wind_height) {
keyboardWindow.transform = CGAffineTransformMakeRotation(-M_PI_2);
self.isAdjustKeyboardFrame = YES;
} else {
keyboardWindow.transform = CGAffineTransformMakeRotation(0);
self.isAdjustKeyboardFrame = NO;
}
keyboardWindow.bounds = CGRectMake(0, 0, WindCS_SCREEN_MIN_LENGTH, WindCS_SCREEN_MAX_LENGTH);
}
}
- (void)deviceOrientationDidChange:(NSNotification *)notificationn {
[self adjustKeyboardWindow];
}
以上希望能夠幫助到有需要的朋友,有問題進一步溝通~