2010-04-10 47 views
34

我不需要在這種情況下指定方向,我只需要檢測它,但我遇到了問題。我有條件代碼,只應該在肖像工作,如果設備在橫向我需要做別的。由於deviceOrientation不一定與interfaceOrientation相同,所以我無法想出測試縱向模式的方法。在iPad上確定UIInterfaceOrientation

我在Google上找到的大多數教程都是強制橫向或進行某種旋轉的方法。我想要做的唯一事情就是確定方向是什麼。這是我的代碼,這是行不通的:

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    //currentOrientation is declared as UIInterfaceOrientation currentOrientation 
    currentOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 
NSLog(@"%@",currentOrientation); // == NULL 
} 

我需要確定interfaceOrientation和程序的值的條件。謝謝你的幫助!

回答

78

您是否知道UIViewController課程的interfaceOrientation屬性?

- (void) viewDidLoad { 
    [super viewDidLoad]; 
    BOOL isPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation); 
    // now do whatever you need 
} 

或者您是否在[[UIDevice currentDevice] orientation]之後?

+0

您的回答非常有幫助。現在,我必須測試的是isPortrait是否爲true,而不是嘗試將定向代碼添加到viewController旋轉方法中 – Justin 2010-04-10 20:06:34

+2

請注意,這似乎並不總是奏效。特別是如果你的控制器是你的應用中的第一個。在我的模擬器測試中[self interfaceOrientation]總是返回爲1.也許它在實際設備上有所不同..至少......很難測試。 – 2010-04-15 02:08:47

+0

我相信當應用第一次啓動時,默認方向是縱向。這可能可以解釋爲什麼[self interfaceOrientation]總是返回1. – 2010-06-03 07:53:42

39

特別是在推出時,我發現以下內容對於UI總是準確的,無論UIDevice說什麼方向。

[UIApplication sharedApplication].statusBarOrientation 
+0

嗯,是不是基本上在原始問題中完全相同的東西?我在測試中發現,當應用程序進入時它總是返回1,因此很沒用。 – 2010-11-28 06:27:01

+0

@Matt,我認爲你是對的。不知道爲什麼我在5月份發佈了它,它看起來確實與原始代碼相同。我可能誤解了這個問題,正如我在設備方向未知時使用上述內容,面朝上或面朝下一樣。 – slycrel 2010-11-30 18:47:32

+0

真棒,在SIM卡上真的很可靠。謝謝! – 2011-01-04 19:06:44

10

self.interfaceOrientation在某些情況下不可靠。例如,重新排列tabbar應用程序中的選項卡會返回不正確的值。

然而[UIApplication sharedApplication].statusBarOrientation總是可靠的。你爲我節省了很多時間。謝謝。

+2

值得注意的是,假設statusBarOrientation在執行初期有效,我看起來好像在didFinishLaunchingWithOptions退出後更新了這個值。這是使用iOS模擬器4.3。 – 2011-08-29 00:49:46

4
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 

if ((orientation == UIInterfaceOrientationLandscapeLeft) 
|| (orientation == UIInterfaceOrientationLandscapeRight)) 
{ 
    //Landscape 
} 
else 
{ 
    //Portrait 
} 
+1

aka UIInterfaceOrientationIsLandscape() – 2016-02-01 22:27:00

1

我知道這是一個很老的帖子。我想添加一個點來說,檢查狀態欄方向會更好。每當您撥打self.interfaceorientation時,每次都會撥打shouldRotateToOrientation。如果你用這種方法編寫了一些代碼,它將被執行。所以要謹慎!

1
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; 
    UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation; 

    if(deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown){ 
     if(debug){ 
      NSLog(@"Nothing to change because it is gone to Flat"); 
     } 
     return; 
    } 
    if(deviceOrientation !=statusBarOrientation){ 
     if(debug){ 
      NSLog(@"\nApple has a bug?:\n UIDeviceOrientation : %d, UIInterfaceOrientation: %d",deviceOrientation, statusBarOrientation ); 
     } 
    } 

你不會相信我,除非你會在控制檯看到第二個輸出! 有些情況 - 它們存在! - 顯示最後的NSLog內容!

比你不得不做一些解決方法去那邊,iOS沒有錯誤,祝你好運!

啊那...論壇版主也許會刪除這篇文章,因爲這並不意味着在他的意見和回答!

我希望它能幫助某人一次,它發生在iPhone太...(有我)

1

混合起來一點:

BOOL isLandscape = self.view.frame.size.width > self.view.frame.size.height; 

(編輯)顯然,以前的答案是在視圖控制器不全屏的情況下,執行此操作的正確方法和此解決方案將失敗。

1
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{</br> 
    if (UIDeviceOrientationIsLandscape(toInterfaceOrientation)) {</br> 
     some instructions; 
    } else { 
     some instructions; 
    } 
} 

這是我的一個程序的片段。 你當然也可以在你的ViewDidLoad通知中使用if語句。

0

由於iOS8上的,API已被棄用或返回無用的結果,如.FaceUp.FaceDown

這是因爲蘋果不希望你使用方向來更新你的UI,而是通過使用大小類,限制和比例(使用superview的n%)。

事實上,取向相關的代碼可能無法提供在整個範圍內設備和

0

我已經投了由@slycrel答案使用情況下(尤其是多任務處理)的好成績,但我想花時間寫這篇文章,並指出一些似乎在這個老問題上丟失的東西,以及關於這個問題的許多其他問題。

的確,蘋果公司並不真的希望我們根據方向變化更新我們的大部分用戶界面,但它仍然是完全可能的,有時還需要在個案情況下,並且這種方式會一直持續到蘋果公司改進它們新的(ISH)的API(如viewWillTransitionToFrame:會方式更加有用比viewWillTransitionToSize:只是說

爲什麼我投了由@slycrel答案是關係到你需要牢記的之間的邏輯有什麼區別UIDeviceOrientationUIInterfaceOrientation

狀態欄表示應用程序當前已知的UIInterfaceOrientation。所有關於FaceUpFaceDown的內容僅與設備的方向有關,不一定是您的應用程序的方向。 無論如何,應用程序不支持設備方向。真的,UIDeviceOrientation可以完全忽略,如果你所要做的只是確保你的界面佈局和動畫適當,這是99%的應用程序開發人員的用例。這是目前從@ slycrel狀態欄UIInterfaceOrientation的答案來實現的:

[UIApplication sharedApplication].statusBarOrientation 

應該指出,在讀寫版本屬性已被棄用,在只讀版本是沒有的。

藉此例如:

  • 我具有支持所有接口取向的應用程序,並支持它們,以及一個根視圖控制器。
  • 現在,我將介紹一個UIViewController,這將導致狀態欄方向變爲橫向。
  • 它的風景方向(左或右)取決於該視圖控制器的preferredInterfaceOrientationForPresentation返回的內容,當前設備的方向以及視圖控制器支持的接口方向(請參閱下一點)。
  • 無論當前設備方向是什麼,狀態欄都會轉到橫向,因爲此視圖控制器僅基於由supportedInterfaceOrientations返回的內容支持橫向。假設我們支持UIInterfaceOrientationMaskLandscape這兩個橫向左右。
  • 我還希望通過旋轉變換有條件地將此視圖控制器設置到位。這隻在從肖像或肖像倒轉到左側風景或右側風景時纔有必要。否則,這將是一個更簡單的演示動畫,無需旋轉。
  • 然後,經過一段時間和設備使用,我解僱了視圖控制器。
  • 現在我想有條件地使用另一個旋轉變換使此視圖控制器脫離屏幕。這隻在從左側風景或右側風景轉到縱向或縱向時纔有必要。否則,這將是一個更簡單的解僱動畫,不旋轉。
  • 此時,根據您的根視圖控制器的首選接口方向和支持的接口方向以及設備當前的UIDeviceOrientation,系統決定的狀態欄方向將變爲適當的值。
  • 因爲我們是要在視圖控制器支持所有接口的方向,如果你的設備的方向朝上或面朝下,你不能可靠地估計基於UIDeviceOrientation下一個UIInterfaceOrientation,你不必反正。
  • 所以...狀態欄方向救援!

前面的例子是可能的,因爲當視圖控制器轉換即將開始時(系統詢問動畫師的轉換委託等),狀態欄方向不會更新。然後在轉換開始動畫時更新(例如,調用animationTransition:時)。這樣,只需使用狀態欄UIInterfaceOrientation的初始值和當前值即可進行比較。

即使不使用視圖控制器轉換,基於狀態欄方向更新視圖仍應該是安全的。

記住,如果你是手動更新狀態欄,如果你是不是在你的Info.plist中使用「查看基於控制器的狀態欄外觀」,那麼你的應用程序的邏輯必須意識到當狀態酒吧將會改變方向。你可能會尋找一對夫婦NSNotification名字對於這些情況,它們是:

  • UIApplicationWillChangeStatusBarOrientationNotification
  • UIApplicationDidChangeStatusBarOrientationNotification

除了這些UIApplicationDelegate方法:

- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration; 
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation; 
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window 

這其他有幫助UIApplication財產:

@property(nonatomic,readonly) NSTimeInterval statusBarOrientationAnimationDuration;