iOS 屏幕旋轉(zhuǎn)/橫豎屏切換適配

前言

現(xiàn)在大部分的智能移動(dòng)設(shè)備通過自動(dòng)旋轉(zhuǎn)赴蝇,能夠自動(dòng)切換去呈現(xiàn)最適合當(dāng)前屏幕顯示的內(nèi)容菩浙,無疑大大提升了使用者的用戶體驗(yàn)。不過作為開發(fā)者,想要達(dá)到完美的適配效果劲蜻,還是要下一番功夫鉆研嘗試才能做得的陆淀。筆者就根據(jù)自己適配屏幕自動(dòng)旋轉(zhuǎn)的工作經(jīng)驗(yàn),在此做一點(diǎn)總結(jié)先嬉。

硬件原理

為了檢測設(shè)備(最關(guān)鍵的就是面子——屏幕)當(dāng)前在三維空間中的朝向轧苫,現(xiàn)在的智能設(shè)備都內(nèi)置了加速計(jì)。這一部分完全參照來源【1】:

通過感知特定方向的慣性力總量疫蔓,加速計(jì)可以測量出加速度和重力含懊,ios設(shè)備內(nèi)的加速計(jì)是一個(gè)三軸加速計(jì),這意味著它能夠檢測出三維空間中的運(yùn)動(dòng)或重力引力衅胀。因此加速計(jì)不但可以指示握持電話的方式(如自動(dòng)旋轉(zhuǎn)功能)岔乔,而且如果電話放在桌子上的話還可以指示電話的正面朝上還是朝下。

加速計(jì)可以測量g引力(g代表重力)拗小,因此加速計(jì)返回值為1.0時(shí)重罪,表示在特定的方向上感知到1g。

  • 如果是靜止握持iphone而沒有任何運(yùn)動(dòng)哀九,那么地球引力對(duì)其施加的力大約為1g
  • 如果是縱向豎直握持剿配,那么設(shè)備會(huì)檢測并報(bào)告在其y軸上施加的力大約為1g
  • 如果是以一定的角度握持,那么1g的力會(huì)分布到不同的軸上阅束,這取決于握持的方式呼胚,在以45度握持時(shí),1g的力會(huì)均勻的分解到兩個(gè)軸上息裸。如果檢測到加速計(jì)值遠(yuǎn)大于1g蝇更,那么可以判斷是突然運(yùn)動(dòng),呼盆,正常使用時(shí)加速計(jì)在任何一個(gè)軸上都不會(huì)檢測到遠(yuǎn)大于1g的值年扩,如果搖動(dòng)、墜落或投擲設(shè)備访圃,那么加速計(jì)便會(huì)在一個(gè)或多個(gè)軸上檢測到很大的力厨幻。

下圖所示加速計(jì)所使用的三軸結(jié)構(gòu)


當(dāng)然,如今的智能手機(jī)里往往不光內(nèi)置了加速計(jì)腿时,往往還有陀螺儀况脆。這一方面的知識(shí)就由大家自行去挖掘吧,很多游戲都是利用它去實(shí)現(xiàn)很自然的操作感批糟。

軟件適配

朝向定義

既然硬件能獲取到當(dāng)前屏幕的朝向格了,蘋果的SDK也一定會(huì)為開發(fā)者提供接口指定有哪些朝向可選,以及如何獲取到當(dāng)前朝向徽鼎。在 UIDevice.h 以及 UIApplication.h 中可見其定義如下:

7種設(shè)備朝向:

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
} __TVOS_PROHIBITED;

5種界面朝向:

// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} __TVOS_PROHIBITED;

可見二者的枚舉值相互之間對(duì)應(yīng)得上盛末。

另外還有可組合使用的OrientationMask定義弹惦,通常在頁面聲明支持的朝向時(shí)用到,后面再展開討論悄但。

typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {
    UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
    UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
    UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
    UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
    UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
    UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
    UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
} __TVOS_PROHIBITED;

朝向獲取和設(shè)置

有了朝向的定義肤频,該如何獲取當(dāng)前的朝向取值呢?
如果是要獲取設(shè)備朝向算墨,可以直接通過 UIDevice 實(shí)例的屬性

// return current device orientation.  this will return UIDeviceOrientationUnknown unless device orientation notifications are being generated.
@property(nonatomic,readonly) UIDeviceOrientation orientation __TVOS_PROHIBITED;       

需要注意注釋的內(nèi)容,也就是必須首先在 UIDevice 朝向通知生成之后才可以正常獲取朝向數(shù)據(jù)汁雷。

也就是要監(jiān)聽UIDevice拋出的系統(tǒng)通知 UIDeviceOrientationDidChangeNotification

[[NSNotificationCenter defaultCenter]addObserver:self 
selector:@selector(updateOrientation:) 
name:UIDeviceOrientationDidChangeNotification object:nil];

不過這里其實(shí)有一點(diǎn)小坑净嘀,那就是還有一對(duì)關(guān)鍵的接口蘋果沒有直接告訴你,那就是

- (void)beginGeneratingDeviceOrientationNotifications __TVOS_PROHIBITED;      // nestable
- (void)endGeneratingDeviceOrientationNotifications __TVOS_PROHIBITED;

必須要在調(diào)用前者之后侠讯,才會(huì)在每次設(shè)備朝向變化時(shí)觸發(fā) UIDeviceOrientationDidChangeNotification 通知挖藏。
不過沒有必要的話,也要及時(shí)調(diào)用后者去結(jié)束對(duì)加速計(jì)數(shù)據(jù)的獲取厢漩,默默的為用戶電池續(xù)航助力膜眠。


類似的,也同樣可以通過監(jiān)聽下面兩個(gè)通知去獲取UIInterfaceOrientation的變化:

UIKIT_EXTERN NSString *const UIApplicationWillChangeStatusBarOrientationNotification __TVOS_PROHIBITED; // userInfo contains NSNumber with new orientation
UIKIT_EXTERN NSString *const UIApplicationDidChangeStatusBarOrientationNotification __TVOS_PROHIBITED;  // userInfo contains NSNumber with old orientation

二者的差異關(guān)鍵是在notification的userInfo中攜帶的值溜嗜,一個(gè)是新的朝向值宵膨,一個(gè)是舊的朝向值,可不要搞反了哦炸宵。

再有是通過UIApplication的下面這個(gè)屬性也可以獲取界面朝向辟躏。

// Explicit setting of the status bar orientation is more limited in iOS 6.0 and later.
@property(readwrite, nonatomic) UIInterfaceOrientation statusBarOrientation NS_DEPRECATED_IOS(2_0, 9_0) __TVOS_PROHIBITED;

有的同學(xué)可能會(huì)有疑問,DeviceOrientation 和 StatusBarOrientation是否可以等同使用土全?關(guān)于這個(gè)問題捎琐,有句話說的好:

紙上得來終覺淺,絕知此事要躬行

動(dòng)手試一試就會(huì)明白裹匙,二者實(shí)則有著本質(zhì)不同瑞凑。

真相在此:前者是指示設(shè)備朝向,而后者則是指示當(dāng)前界面中狀態(tài)欄的朝向概页;在[UIDevice beginGeneratingDeviceOrientationNotifications]之后籽御,每次設(shè)備旋轉(zhuǎn),都會(huì)有UIDeviceOrientationDidChangeNotification的通知生成绰沥,而 UIApplicationWillChangeStatusBarOrientationNotification 則是當(dāng)前顯示controller支持對(duì)應(yīng)的InterfaceOrientation時(shí)才會(huì)觸發(fā)篱蝇。

所以可能會(huì)出現(xiàn)這種情況,DeviceOrientation 值 為UIDeviceOrientationLandscapeLeft徽曲,但I(xiàn)nterfaceOrientation 值卻是 UIInterfaceOrientationPortrait零截,下圖就是典型的例子:


另外,某些應(yīng)用場景下秃臣,還需要去手動(dòng)設(shè)置屏幕旋轉(zhuǎn)涧衙,比如播放器往往都既支持自動(dòng)旋轉(zhuǎn)屏幕去切換全屏播放哪工,同時(shí)也允許用戶去手動(dòng)切換全屏或小屏播放。但翻看了半天API描述和文檔弧哎,要么就是不提供接口雁比,要么就是警告設(shè)置受限,那要怎么做呢撤嫩?其實(shí)很簡單偎捎,只要兩行代碼搞定:

NSNumber *value = @(UIInterfaceOrientationPortrait);//或者別的想要的值
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

App及頁面適配

  • App全局配置

App中全局配置支持朝向的地方,最方便的就是在工程的Target中了序攘,如圖所示:

理所當(dāng)然全局配置其優(yōu)先級(jí)當(dāng)然是最高的茴她,即使某個(gè)頁面聲明支持某Orientation,但全局配置中并沒有選中對(duì)應(yīng)的Device Orientation程奠,是不會(huì)起效的丈牢。

  • 單個(gè)頁面配置
    具體到某個(gè)頁面(controller)層級(jí)的配置,UIViewController提供了如下的回調(diào)方法

      // New Autorotation support.
      - (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
      - (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
      // Returns interface orientation masks.
      - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
    

第一個(gè)方法在首次進(jìn)入controller以及屏幕方向未鎖定且觸發(fā)旋轉(zhuǎn)時(shí)會(huì)被系統(tǒng)調(diào)用(且不重寫的話瞄沙,默認(rèn)返回值為YES)己沛,如果返回NO,那么表明該頁面不支持對(duì)屏幕旋轉(zhuǎn)做適配距境;若返回YES申尼,則表明支持旋轉(zhuǎn),但具體適配了哪幾個(gè)朝向肮疗,則依賴于supportedInterfaceOrientations 方法的返回值晶姊,也就是UIInterfaceOrientationMask類型的Option組合。

看起來并不復(fù)雜對(duì)不對(duì)伪货?在設(shè)定了App的全局配置们衙,并在相應(yīng)的controller中實(shí)現(xiàn)了這些回調(diào)之后發(fā)現(xiàn),有同學(xué)可能會(huì)失望地發(fā)現(xiàn)碱呼,設(shè)備旋轉(zhuǎn)時(shí)這些方法卻并沒有期望地那樣被調(diào)到蒙挑,這是為什么呢?

通過反復(fù)驗(yàn)證愚臀,發(fā)現(xiàn)其實(shí)系統(tǒng)確實(shí)會(huì)調(diào)用這個(gè)方法忆蚀,但默認(rèn)執(zhí)行粒度是到系統(tǒng)級(jí)的 Container View Controller(UINavigationController/UITabBarController)為止(其實(shí)直接掛在UIWindow上作為其rootViewController的UIViewController對(duì)象的 shouldAutoRotate 方法也會(huì)得到調(diào)用,但畢竟大多數(shù)情況下姑裂,我們不會(huì)用這么簡單的組合結(jié)構(gòu)的)馋袜。所以我們額外需要實(shí)現(xiàn)的一步,就是轉(zhuǎn)發(fā)這個(gè)調(diào)用消息到我們真正想要處理的那個(gè)controller上舶斧。當(dāng)然欣鳖,可以通過hook系統(tǒng)類的對(duì)應(yīng)方法去做實(shí)現(xiàn),但筆者采用的是在自行定義的UINavigationController繼承類中重寫這些方法:

#pragma mark Orientation

- (BOOL)shouldAutorotate
{
    BOOL shouldAutorotate = NO;
    UIViewController *viewController;
    if (IOS_VERSION_FLOAT_VALUE >= 8.0)
    {
        viewController = [self visibleViewController];
    }
    else
    {
        viewController = [self topViewController];
    }
    
    if ([viewController isKindOfClass:K12RootViewController.class] && ((K12RootViewController *)viewController).visibleNav) {
        viewController = ((K12RootViewController *)viewController).visibleNav;
    }
    
    if (viewController.ht_currentChildViewController) {
        viewController = viewController.ht_currentChildViewController;
    }
    
    
    if ([viewController isKindOfClass:[UIViewController class]])
    {
        shouldAutorotate = [(UIViewController *)viewController shouldAutorotate];
    }
    
    //彈框也要支持旋轉(zhuǎn)
    if ([viewController isKindOfClass:K12PlayerController.class] || ((IOS_VERSION_FLOAT_VALUE >= 8.0) ? [viewController isKindOfClass:UIAlertController.class] : NO)) {
        return YES;
    }
    else {
        return NO;
    }
    return shouldAutorotate;;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{    
    NSUInteger supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
    UIViewController *viewController;
    if (IOS_VERSION_FLOAT_VALUE >= 8.0)
    {
        viewController = [self visibleViewController];
    }
    else
    {
        viewController = [self topViewController];
    }
    
    if ([viewController isKindOfClass:K12RootViewController.class] && ((K12RootViewController *)viewController).visibleNav) {
        viewController = ((K12RootViewController *)viewController).visibleNav;
    }
    
    if (viewController.ht_currentChildViewController) {
        viewController = viewController.ht_currentChildViewController;
    }

    //向UIAlertController發(fā)送supportedInterfaceOrientations消息會(huì)crash……
    if ([viewController isKindOfClass:UIAlertController.class]) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    
    if ([viewController isKindOfClass:[UIViewController class]])
    {
        supportedInterfaceOrientations = [(UIViewController *)viewController supportedInterfaceOrientations];
    }
    
    return supportedInterfaceOrientations;
}

可以看到其中有各種各樣case的處理茴厉,原因就是除了播放頁面支持豎屏泽台、左橫屏以及右橫屏(UIInterfaceOrientationMaskAllButUpsideDown)之外什荣,我們產(chǎn)品中的其他頁面都是只支持橫屏顯示的(UIInterfaceOrientationMaskPortrait),同時(shí)在當(dāng)前頁面上有UIAlertController(iOS8 之后)彈出時(shí)怀酷,也要設(shè)置其支持跟隨屏幕旋轉(zhuǎn)稻爬。

類似的,如果 UIWindow 對(duì)象的 rootViewController 是 UITabBarController 的話蜕依,則需要轉(zhuǎn)發(fā)消息給其 selectedViewController 屬性對(duì)象桅锄,具體實(shí)現(xiàn)就不再贅言啦。

  • 踩過的坑

說起來样眠,項(xiàng)目開發(fā)中不踩點(diǎn)坑簡直對(duì)不起程序猿這個(gè)title啊 —— 前面提到過

...掛在UIWindow上作為其rootViewController的UIViewController對(duì)象的 shouldAutoRotate 方法也會(huì)得到調(diào)用

這里往往會(huì)隱藏一個(gè)問題竞滓,默認(rèn)在AppDelegate.m中,我們會(huì)這樣做:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    
    self.k12RootController = [[K12RootViewController alloc] init];
    K12NavigationController *navController = [[K12NavigationController alloc] initWithRootViewController: self.k12RootController];
    
    self.window.rootViewController = navController;
    
    [self.window makeKeyAndVisible];
    ...
}

當(dāng)然吹缔,這看起來沒有問題。但是假如App中還存在別的 UIWindow 對(duì)象呢锯茄?旋轉(zhuǎn)時(shí)厢塘,它的rootViewController 的 shouldAutoRotate 方法也將被調(diào)用,若沒有重寫過肌幽,則其默認(rèn)返回YES晚碾;如果與其他 UIWindow對(duì)象(特別是keyWindow) 所呈現(xiàn)的最頂部頁面的返回值不一致,就會(huì)出現(xiàn)一些神奇的表現(xiàn)喂急,如下圖所示:

切換到橫屏下時(shí)格嘁,狀態(tài)欄居然消失了!廊移!該情況的出現(xiàn)吸申,就是因?yàn)樵谠摯痤}頁面的上一個(gè)頁面(播放頁面)中使用了一個(gè)第三方組件去繪制Menu剪撬,而其設(shè)計(jì)存在瑕疵,在生成Menu對(duì)象而非顯示時(shí)就已經(jīng)生成了一個(gè)UIWindow對(duì)象并持有了它。然后在進(jìn)入答題頁面時(shí)丙躏,雖然對(duì)應(yīng)的controller的 shouldAutoRotate 方法返回了 NO,但Menu對(duì)應(yīng)的UIWindow對(duì)象其rootViewController默認(rèn)返回YES止毕,導(dǎo)致出現(xiàn)頁面保持豎屏顯示套才,但狀態(tài)欄響應(yīng)了旋轉(zhuǎn)的奇怪現(xiàn)象。

這個(gè)問題最終還是通過hook掉 UIViewController 的shouldAutoRotate 方法辱揭,去追蹤究竟是哪個(gè)controller對(duì)象返回了默認(rèn)值 YES 才最終大白天下离唐。這也提醒我們,對(duì)開源庫的品質(zhì)也是謹(jǐn)慎對(duì)待的问窃,往往太復(fù)雜業(yè)務(wù)場景亥鬓,還是需要自己去定制功能才能滿足。

總結(jié)

這篇文章也算是在參與某產(chǎn)品開發(fā)過程中泡躯,屏幕旋轉(zhuǎn)適配過程中贮竟,踩了不少坑之后經(jīng)驗(yàn)教訓(xùn)的一個(gè)總結(jié)丽焊。當(dāng)然,想要實(shí)現(xiàn)頁面的橫豎屏切換效果咕别,并不是只有這一條路徑技健,還可以通過UIView的transform屬性去實(shí)現(xiàn),不過那就是另一個(gè)話題啦 惰拱。

@property(nonatomic) CGAffineTransform transform;   // default is CGAffineTransformIdentity. animatable

ヾ( ̄▽ ̄)ByeBye

參考資料

【1】ios 關(guān)于屏幕旋轉(zhuǎn)和屏幕晃動(dòng)

【2】iOS指定頁面屏幕旋轉(zhuǎn)雌贱,手動(dòng)旋轉(zhuǎn)(某app實(shí)現(xiàn)功能全過程)

【3】iOS: Using UIDeviceOrientation to Determine Orientation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市偿短,隨后出現(xiàn)的幾起案子欣孤,更是在濱河造成了極大的恐慌,老刑警劉巖昔逗,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件降传,死亡現(xiàn)場離奇詭異,居然都是意外死亡勾怒,警方通過查閱死者的電腦和手機(jī)婆排,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笔链,“玉大人段只,你說我怎么就攤上這事〖ǎ” “怎么了赞枕?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坪创。 經(jīng)常有香客問我炕婶,道長,這世上最難降的妖魔是什么莱预? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任古话,我火速辦了婚禮,結(jié)果婚禮上锁施,老公的妹妹穿的比我還像新娘陪踩。我一直安慰自己,他們只是感情好悉抵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布肩狂。 她就那樣靜靜地躺著,像睡著了一般姥饰。 火紅的嫁衣襯著肌膚如雪傻谁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天列粪,我揣著相機(jī)與錄音审磁,去河邊找鬼谈飒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛态蒂,可吹牛的內(nèi)容都是我干的杭措。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼钾恢,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼手素!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘩蚪,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泉懦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后疹瘦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體崩哩,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年言沐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琢锋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呢灶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钉嘹,到底是詐尸還是另有隱情鸯乃,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布跋涣,位于F島的核電站缨睡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏陈辱。R本人自食惡果不足惜奖年,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沛贪。 院中可真熱鬧陋守,春花似錦、人聲如沸利赋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媚送。三九已至中燥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塘偎,已是汗流浹背疗涉。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國打工拿霉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咱扣。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓绽淘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偏窝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子收恢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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

  • 1.監(jiān)聽屏幕旋轉(zhuǎn)方向 在處理iOS橫豎屏?xí)r,經(jīng)常會(huì)和UIDeviceOrientation祭往、UIInterface...
    彬至睢陽閱讀 2,537評(píng)論 1 6
  • [這是第11篇] 導(dǎo)語: iOS App中大多數(shù)頁面是只展示豎屏下的效果伦意,但是少部分頁面需要支持橫豎屏。本文分別介...
    南華coder閱讀 14,496評(píng)論 18 93
  • iOS屏幕旋轉(zhuǎn)學(xué)習(xí)筆記iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法 1硼补、基本知識(shí)點(diǎn)解讀 了解屏幕旋轉(zhuǎn)首先需要區(qū)分兩種 o...
    Laughingg閱讀 13,509評(píng)論 13 39
  • 一: 序 二: 基本知識(shí)點(diǎn)了解 三: 屏幕旋轉(zhuǎn)流程 四: 屏幕旋轉(zhuǎn)設(shè)置 四: 結(jié)言 序: 這幾天項(xiàng)目要適...
    Luyc_Han閱讀 495評(píng)論 0 1
  • 時(shí)光匆匆流去一別竟是半生回憶想起您循循善誘的教誨想起您如沐春風(fēng)的話語想起您在燈下批閱作業(yè)的身影想起您在三尺講臺(tái)上揮...
    哲語細(xì)細(xì)閱讀 332評(píng)論 26 32