IOS屏幕旋轉(zhuǎn)(自動旋轉(zhuǎn)、手動旋轉(zhuǎn)闯传、兼容IOS6之前系統(tǒng))

概述:

在iOS6之前的版本中谨朝,通常使用 shouldAutorotateToInterfaceOrientation 來單獨控制某個UIViewController的方向,需要哪個viewController支持旋轉(zhuǎn)甥绿,只需要重寫shouldAutorotateToInterfaceOrientation方法字币。
但是iOS 6里屏幕旋轉(zhuǎn)改變了很多,之前的 shouldAutorotateToInterfaceOrientation 被列為 DEPRECATED 方法妹窖,查看UIViewController.h文件也可以看到:

// Applications should use supportedInterfaceOrientations and/or shouldAutorotate..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0);

程序?qū)⑹褂萌缦?個方法來代替:

- (BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;

除了重寫這個2個方法纬朝,IOS6里面要旋轉(zhuǎn)還有一些需要注意的地方,下面會細述骄呼。另外還有一個硬性條件共苛,需要在Info.plist文件里面添加程序支持的所有方向判没,可以通過以下2種方式添加:

另外要兼容IOS6之前的系統(tǒng),要保留原來的 shouldAutorotateToInterfaceOrientation 方法隅茎,還有那些 willRotateToInterfaceOrientation 等方法澄峰。

IOS6自動旋轉(zhuǎn)設(shè)置:

IOS6里面,控制某個viewController旋轉(zhuǎn)并不是像IOS5或者IOS4一樣在這個viewController里面重寫上面那2個方法辟犀,而是需要在這個viewController的rootViewController(根視圖控制器)里面重寫俏竞,怎么解釋呢?就是最前面的那個viewController堂竟,直接跟self.window接觸的那個controller魂毁,比如以下代碼:

UIViewController *viewCtrl = [[UIViewController alloc] init];
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
if ([window respondsToSelector:@selector(setRootViewController:)]) {
    self.window.rootViewController = navCtrl;
} else {
    [self.window addSubview:navCtrl.view];
}

如果需要設(shè)置viewCtrl的旋轉(zhuǎn),那么不能在UIViewController里面重寫shouldAutorotate和supportedInterfaceOrientations方法出嘹,而是需要在navCtrl里面設(shè)置席楚,又因為UINavigationController是系統(tǒng)控件,所以這里需要新建一個UINavigationController的子navigationController的子類税稼,然后在里面實現(xiàn)shouldAutorotate和supportedInterfaceOrientations方法烦秩,比如:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

- (BOOL)shouldAutorotate{
    return YES;
}

eg1:如果上面的例子是self.window.rootViewController = viewCtrl,而不是navCtrl郎仆,那么上面的那2個控制旋轉(zhuǎn)的方法就應(yīng)該寫在UIViewController里面只祠!
eg2:如果viewCtrl又pushViewController到viewCtrl2,需要設(shè)置viewCtrl2的旋轉(zhuǎn)扰肌,怎么辦呢抛寝? 還是在navCtrl里面控制,因為viewCtrl和viewCtrl2的rootViewController都是navCtrl狡耻,一般的寫法都是

UIViewController *viewCtrl2 = [[UIVewController alloc] init];
[self.navigationController.navigationController pushViewController:viewCtrl2 animated:YES];

所以要控制一個UINavigationController push到的所有viewController的旋轉(zhuǎn)墩剖,那么就得在navCtrl里面區(qū)分是哪個viewController,以便對他們一一控制夷狰!同樣如果rootViewController是UITabbarController岭皂,那么需要在子類化的UITabbarController里面重寫那2個方法,然后分別控制沼头!

但是有時候我初始化UINavigationController的時候爷绘,并不知道所有我所有需要push到的viewController,那么這里有一個通用的方法进倍,就是讓viewController自己來控制自己土至,首先在navCtrl里面的實現(xiàn)方法改為以下方式:

- (BOOL)shouldAutorotate  
{  
    return self.topViewController.shouldAutorotate;  
}  

- (NSUInteger)supportedInterfaceOrientations  
{  
    return self.topViewController.supportedInterfaceOrientations;  
}

全部調(diào)用self.topViewController,就是返回當(dāng)前呈現(xiàn)出來的viewController里面的設(shè)置猾昆,然后在viewCtrl陶因、viewCtrl2等等這些viewController里面重寫shouldAutorotate和supportedInterfaceOrientations,以方便設(shè)置每個viewController的旋轉(zhuǎn)

eg3:如果viewCtrl 是 presentModalViewController 到 viewCtrl3垂蜗,那么viewCtrl3的旋轉(zhuǎn)設(shè)置就不在navCtrl里面了楷扬!如果presentModalViewController的viewController是navController解幽、tabbarController包裝過的viewCtrl3,那么就應(yīng)在新包裝的navController烘苹、tabbarController里面設(shè)置躲株,如果是直接presentModalViewController到viewCtrl3,那么就在viewCtrl3里面設(shè)置

IOS5镣衡、IOS4自動旋轉(zhuǎn)設(shè)置

這個簡單很多霜定,沒有上面的硬性條件,只需要在需要旋轉(zhuǎn)的viewController里面重寫 shouldAutorotateToInterfaceOrientation 方法就行

手動旋轉(zhuǎn)

手動旋轉(zhuǎn)也有2種方式廊鸥,一種是直接設(shè)置 UIDevice 的 orientation望浩,但是這種方式不推薦,上傳appStore有被拒的風(fēng)險:

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
    [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];
}

第二種是假旋轉(zhuǎn)黍图,并沒有改變 UIDevice 的 orientation曾雕,而是改變某個view的 transform奴烙,利用 CGAffineTransformMakeRotation 來達到目的,比如:

self.view.transform = CGAffineTransformMakeRotation(M_PI/2)  

下面講解采用第二種方式的各版本手動旋轉(zhuǎn):
思想是首先設(shè)置 statusBarOrientation切诀,然后再改變某個view的方向跟 statusBarOrientation 一致!

IOS6手動旋轉(zhuǎn):

  1. 那既然是旋轉(zhuǎn)丰滑,最少也得有2個方向,那么還是少不了上面說的那個硬性條件倒庵,先在plist里面設(shè)置好所有可能需要旋轉(zhuǎn)的方向褒墨。既然是手動旋轉(zhuǎn),那么就要關(guān)閉自動旋轉(zhuǎn):

     - (BOOL)shouldAutorotate{
         return NO;
     }
    
  2. 手動觸發(fā)某個按鈕郁妈,調(diào)用方法绍申,這個方法的實現(xiàn)如下

     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
     self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
     self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);
    

注意:

  • 只需要改變self.view.transform噩咪,那么self.view的所有subview都會跟著自動變;其次因為方向變了极阅,所以self.view的大小需要重新設(shè)置胃碾,不要使用self.view.frame筋搏,而是用bounds。
  • 如果shouldAutorotate 返回YES的話奔脐,下面設(shè)置setStatusBarOrientation 是不管用的栏账!setStatusBarOrientation只有在shouldAutorotate 返回NO的情況下才管用栈源!

IOS5、IOS4手動旋轉(zhuǎn):

  1. 在需要手動旋轉(zhuǎn)的viewController里的 shouldAutorotateToInterfaceOrientation 方法設(shè)置 interfaceOrientation == [UIApplicationsharedApplication].statusBarOrientation

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
         return (interfaceOrientation == [UIApplication sharedApplication].statusBarOrientation);
     }
    
  2. 手動觸發(fā)某個按鈕甚垦,調(diào)用方法,這個方法的實現(xiàn)如下:

     [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
     self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
     self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);
    

注意:只需要改變self.view.transform闭翩,那么self.view的所有subview都會跟著自動變迄埃;其次因為方向變了,所以self.view的大小需要重新設(shè)置侄非,不要使用self.view.frame,而是用bounds者疤。

經(jīng)驗分享:

  1. IOS6里面叠赦,如果一個項目里面需要各種旋轉(zhuǎn)支持,有自動除秀,有手動,那么我們可以新建2個navController或者tabbarController的子類泳姐,一個是不旋轉(zhuǎn),一個旋轉(zhuǎn)棍好,那么所有需要旋轉(zhuǎn)的UINavigationController都可以用這個子類來代替!包括我們可以定制短信呀扒怖、郵件呀的旋轉(zhuǎn)业稼!
  2. supportedInterfaceOrientations 方法一般是寫UIInterfaceOrientationMask方向,但是如果程序要兼容4.3以下的SDK(4.3以下的SDK必須是4.5以下的Xcode,不支持IOS6)骡楼,那么在用4.5以下的Xcode編譯的時候通不過稽鞭!所以可以用statusBarOrientation代替或者直接寫死數(shù)字!
    -(NSUInteger)supportedInterfaceOrientations{
    return [UIApplication sharedApplication].statusBarOrientation;
    }
  3. 一般都不建議在程序里面直接調(diào)用 UIDeviceOrientation 的方向朦蕴,而是用 UIInterfaceOrientation,他們之間是不同的涉茧!
    UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft

看到嗎疹娶,左右是反的!Xcode圖形化設(shè)置方向也是以 UIInterfaceOrientation 為準(zhǔn)钳垮,就是home按鍵所在的方向沛膳。
原文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子倚舀,更是在濱河造成了極大的恐慌,老刑警劉巖风罩,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舵稠,死亡現(xiàn)場離奇詭異,居然都是意外死亡室琢,警方通過查閱死者的電腦和手機落追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巢钓,“玉大人,你說我怎么就攤上這事症汹。” “怎么了背镇?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵芽世,是天一觀的道長。 經(jīng)常有香客問我济瓢,道長,這世上最難降的妖魔是什么蔑鹦? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任箕宙,我火速辦了婚禮,結(jié)果婚禮上哟忍,老公的妹妹穿的比我還像新娘陷寝。我一直安慰自己,他們只是感情好凤跑,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扔仓,像睡著了一般咖耘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鲤看,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音找筝,去河邊找鬼。 笑死曹抬,一個胖子當(dāng)著我的面吹牛急鳄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疾宏,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼坎藐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岩馍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤疫铜,失蹤者是張志新(化名)和其女友劉穎双谆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佃乘,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡趣避,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年新翎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片地啰。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡亏吝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情许赃,我是刑警寧澤馆类,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站乾巧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咳胃。R本人自食惡果不足惜旷太,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望标沪。 院中可真熱鬧嗜傅,春花似錦金句、人聲如沸吕嘀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棕洋。三九已至,卻和暖如春掰盘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奢驯。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工次绘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撒遣,地道東北人管跺。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像伙菜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子火的,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容