iOS旋轉(zhuǎn)屏幕設(shè)置總結(jié)

iOS開發(fā)中挟纱,經(jīng)常會(huì)碰到某些頁面需要支持橫屏顯示撕氧,某些又僅支持豎屏顯示摧找,那怎么樣才能比較完美的實(shí)現(xiàn)各個(gè)界面的橫豎屏設(shè)置,有不相互影響呢牢硅?
經(jīng)過幾個(gè)項(xiàng)目的實(shí)踐比較蹬耘,個(gè)人感覺讓各個(gè)viewController自己來控制自己的橫豎屏顯示是最好的!<跤唷综苔!
問題是怎么設(shè)置才最簡單方便不容易出錯(cuò)~

注:以下全部是iOS6以后的方法,iOS6之前的太久遠(yuǎn)了位岔,就不提了如筛;
這里僅涉及設(shè)置的方法,具體轉(zhuǎn)屏的方法抒抬,有空再寫杨刨;

首先,要確定APP支持哪些方向

可以通過兩種方式來確定:

  1. 在工程設(shè)置處勾選


    工程設(shè)置

    或者在或者在info.plist中設(shè)置


    info.plist中設(shè)置

    這兩個(gè)地方是等價(jià)的擦剑,改了其中一個(gè)地方妖胀,另一個(gè)也會(huì)跟著變;
  2. 在AppDelegate中實(shí)現(xiàn)方法
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return .allButUpsideDown
    }

1或者2必須實(shí)現(xiàn)至少一個(gè)才行惠勒;
什么赚抡?你說兩個(gè)都沒實(shí)現(xiàn)?那系統(tǒng)會(huì)按默認(rèn)的.allButUpsideDown來處理纠屋。涂臣。。
什么什么巾遭?你說兩個(gè)都實(shí)現(xiàn)了設(shè)置的值還不一樣肉康?那系統(tǒng)會(huì)以AppDelegate中實(shí)現(xiàn)的代碼為準(zhǔn)。灼舍。吼和。

其次,要確定viewController支持的方向

viewController通過以下方法來確定:

    open override var shouldAutorotate: Bool {
        return false
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
         return .portrait
    }
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }

第一個(gè)方法確定viewController是否會(huì)自動(dòng)旋轉(zhuǎn)骑素,第二個(gè)方法確定viewController支持哪些方向炫乓,第三方方法確定viewController彈出來時(shí)的方向;
需要注意的是:
這幾個(gè)方法只有當(dāng)viewController是window的rootViewController或者viewController是present出來時(shí)献丑,才會(huì)起作用末捣!
這幾個(gè)方法只有當(dāng)viewController是window的rootViewController或者viewController是present出來時(shí),才會(huì)起作用创橄!
這幾個(gè)方法只有當(dāng)viewController是window的rootViewController或者viewController是present出來時(shí)箩做,才會(huì)起作用!
重要的事情說三遍

也就是說妥畏,如果app是常見的tabBarController+navigationController+viewController的結(jié)構(gòu)的話邦邦,rootViewController是tabBarController安吁,
所以只有tabBarController的這三個(gè)方法會(huì)被調(diào)用!
那怎么實(shí)現(xiàn)開頭說的讓各個(gè)viewController來控制自己的方向呢燃辖?
其實(shí)很簡單鬼店,因?yàn)閠abBarController和navigationController都是viewController的容器,讓他們返回當(dāng)前顯示的viewController的相應(yīng)方法就行了黔龟!
以navigationController為例妇智,就是:

    open override var shouldAutorotate: Bool {
        if let viewController = self.topViewController {
            return viewController.shouldAutorotate
        } else {
            return false
        }
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let viewController = self.topViewController {
            return viewController.supportedInterfaceOrientations
        }  else {
            return .portrait
        }
    }
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        if let viewController = self.topViewController {
            return viewController.preferredInterfaceOrientationForPresentation
        }  else {
            return .portrait
        }
    }

注意:viewController最終支持的方向是以上app支持方向和viewController支持方向兩個(gè)規(guī)則的交集,如果交集為空氏身,就會(huì)crashN±狻!观谦!

基本原理知道了拉盾,也該回答最初的問題了,簡單方便又不容易出錯(cuò)的設(shè)置方法就是

結(jié)論:寫基類

這里需要至少三個(gè)基類豁状,分別繼承tabBarController捉偏,navigationController和viewController;
在其中分別實(shí)現(xiàn)轉(zhuǎn)屏方法泻红,然后項(xiàng)目中所有的其他類夭禽,都繼承這幾個(gè)基類;
然后谊路,在需要支持不同方向的viewController中讹躯,重載轉(zhuǎn)屏的三個(gè)方法,就大功告成了~
例:
這里OJSTabBarController缠劝,OJSNavigationController潮梯,OJSViewController分別集成自對應(yīng)的UIViewController

extension OJSTabBarController {
    
    //這里,如果selectedViewController是navigationController惨恭,因?yàn)閚avigationController也是返回它的topViewController的狀態(tài)秉馏,所以最終還是各個(gè)viewController自己來控制自己的狀態(tài)
    
    open override var shouldAutorotate: Bool {
        if let tempViewController = self.selectedViewController {
            return tempViewController.shouldAutorotate
        } else {
            return false
        }
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let tempViewController = self.selectedViewController {
            return tempViewController.supportedInterfaceOrientations
        } else {
            return UIInterfaceOrientationMask.portrait
        }
    }
    
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        if let tempViewController = self.selectedViewController {
            return tempViewController.preferredInterfaceOrientationForPresentation
        } else {
            return UIInterfaceOrientation.portrait
        }
    }
}

extension OJSNavigationController {
    //這里只需要返回self.topViewController的相應(yīng)屬性,讓各個(gè)viewController自己控制就行了
    //present出來的viewController本來就是受自己控制脱羡,跟nav無關(guān)
    
    open override var shouldAutorotate: Bool {
        if let viewController = self.topViewController {
            return viewController.shouldAutorotate
        } else {
            return false
        }
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let viewController = self.topViewController {
            return viewController.supportedInterfaceOrientations
        }  else {
            return .portrait
        }
    }
    
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        if let viewController = self.topViewController {
            return viewController.preferredInterfaceOrientationForPresentation
        }  else {
            return .portrait
        }
    }
}



extension OJSViewController {
    
    open override var shouldAutorotate: Bool {
        return false
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
         return .portrait
    }
    
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
}

這樣做的好處是:
每個(gè)viewController都有默認(rèn)的轉(zhuǎn)屏設(shè)置萝究,不會(huì)因?yàn)槁懥舜a而出現(xiàn)不應(yīng)該出現(xiàn)的旋轉(zhuǎn);
每個(gè)viewController是自己控制自己的方向锉罐,不會(huì)對前后viewController有任何影響
需要特殊方向的viewController帆竹,僅實(shí)現(xiàn)自己的方法就行,不用再在rootViewController中做一大堆判斷脓规;
栽连。。侨舆。秒紧。舷暮。。

彩蛋

之前提交appstore時(shí)遇到個(gè)極其奇葩的問題噩茄,蘋果審核人員用iPad裝我們的iPhone app,然后發(fā)現(xiàn)他的iPad橫著啟動(dòng)app時(shí)界面全亂了复颈,
然后他就截了個(gè)圖绩聘,把我們的app拒掉了。耗啦。凿菩。。帜讲。衅谷。
當(dāng)時(shí)我的內(nèi)心真是極其崩潰的,似将,获黔,iPad豎著啟動(dòng)app時(shí),就一切正常在验,橫著啟動(dòng)app時(shí)玷氏,界面就亂套了。腋舌。盏触。
這想想應(yīng)該是蘋果的鍋啊?榻取T薇纭!
后來偶然發(fā)現(xiàn)個(gè)非常規(guī)的解決方法:
在工程設(shè)置處設(shè)置app只支持portrait授艰,然后在AppDelegate中設(shè)置為支持其他辨嗽;這樣app啟動(dòng)的時(shí)候就會(huì)強(qiáng)制用豎屏方式啟動(dòng),
iPad上的問題就解決了想诅。召庞。。蘋果也給審核通過了来破。篮灼。。

有什么問題徘禁,歡迎討論~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诅诱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子送朱,更是在濱河造成了極大的恐慌娘荡,老刑警劉巖干旁,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炮沐,居然都是意外死亡争群,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門大年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來换薄,“玉大人,你說我怎么就攤上這事翔试∏嵋” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵垦缅,是天一觀的道長冲泥。 經(jīng)常有香客問我,道長壁涎,這世上最難降的妖魔是什么凡恍? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮怔球,結(jié)果婚禮上咳焚,老公的妹妹穿的比我還像新娘。我一直安慰自己庞溜,他們只是感情好革半,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著流码,像睡著了一般又官。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漫试,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天六敬,我揣著相機(jī)與錄音,去河邊找鬼驾荣。 笑死外构,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的播掷。 我是一名探鬼主播审编,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歧匈!你這毒婦竟也來了垒酬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎勘究,沒想到半個(gè)月后矮湘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡口糕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年缅阳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片景描。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡券时,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伏伯,到底是詐尸還是另有隱情,我是刑警寧澤捌袜,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布说搅,位于F島的核電站,受9級特大地震影響虏等,放射性物質(zhì)發(fā)生泄漏弄唧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一霍衫、第九天 我趴在偏房一處隱蔽的房頂上張望候引。 院中可真熱鬧,春花似錦敦跌、人聲如沸澄干。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麸俘。三九已至,卻和暖如春惧笛,著一層夾襖步出監(jiān)牢的瞬間从媚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工患整, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拜效,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓各谚,卻偏偏與公主長得像紧憾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子昌渤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫稻励、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評論 4 62
  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多,會(huì)對里面所有的內(nèi)容的引用計(jì)數(shù)+1望抽,想要解決就用__block...
    炙冰閱讀 2,486評論 1 14
  • 這段時(shí)間瘋狂迷上了咖啡館(之前是書店)加矛,若恰逢星期五持廣發(fā)卡喝咖啡打折的話,這一天煤篙,我是盡量不缺席的斟览。其他時(shí)間也是...
    木子文雙閱讀 524評論 2 2
  • (1)splice會(huì)改變原來是數(shù)組,splice(start,length) (2)slice會(huì)構(gòu)建新數(shù)組辑奈,sli...
    何幻閱讀 278評論 0 0
  • 后來發(fā)現(xiàn)苛茂,應(yīng)該在協(xié)議處添加上該有的協(xié)議 然后警告就取消了
    thanksdanny閱讀 221評論 0 0