web-dev-qa-db-ja.com

iOS:ロード時のデバイスの向き

私のアプリが読み込まれたとき、現在の向きがわからないようです:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
    NSLog(@"portrait");// only works after a rotation, not on loading app
}

デバイスを回転させると、正しい向きになりますが、向きを変更せずにアプリを読み込むと、[[UIDevice currentDevice] orientation]は現在の向きを知りません。

アプリを初めて読み込むときにこれを確認する別の方法はありますか?

52
Nic Hubbard

私はこれがうまくいくと思う:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;

UIDeviceリファレンスによると:
見積もり:
"beginGeneratingDeviceOrientationNotificationsを呼び出して方向通知が有効になっていない限り、このプロパティの値は常に0を返します。
当初、このプロパティには常に現在の向きが含まれていると想定していましたが、明らかにそうではありませんでした。方向プロパティに通常アクセスする他の状況では、通知をオンにすることは舞台裏で処理されているため、アプリデリゲート内で手動で行う必要があることは明らかではなかったと思います

11
Iducool

まだ誰も触れていないことの1つは、UIDeviceOrientation型をUIInterfaceOrientation変数に格納していることです。それらは異なっており、等しく扱われるべきではありません。 UIDeviceOrientationLeftUIInterfaceOrientationRightと等しいことに注意してください(インターフェイスはデバイスとは反対の方向に回転するため)。

2
Jeff Kelley

ロード時のデバイスの向きは.Unknownまたは.FaceUp。縦向きか横向きかを判断するために、次のようにstatusBarOrientationをバックアップとして使用します。

    var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait

    if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
        portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
    }

このようにして、portraitOrientationは常にデバイスがポートレートモードにあるかどうかを確認し、そうでない場合は横向きになります。アプリを初めてロードするときでも。

2
Marijn

次の通知を内部に挿入することでそれを行うことができます

-(void)viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

次に、クラス内に次のメソッドを配置します

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
         //Do your textField animation here
    }
}

上記の方法では、iPadまたはiPhoneのステータスバーの向きを確認し、それに応じて、必要な向きでアニメーションを作成します。

2
Aragon

Swift @Marjinのコードに基づきます。

var portraitOrientation = UIDevice.current.orientation == .portrait

if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
     portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}

if(portraitOrientation)
{
     // Portrait
}
else
{

}
1
Nacho Badia

ステータスバーから方向を取得するには、plistファイルですべての方向を有効にすることも重要です。

1
NicoRaf

加速度計を使用して、読み取り値を取得し、UIAccelerometer、sharedAccelerometerを取得し、デリゲートを設定し、読み取り値を取得し、そこから方向を把握します。

0
DavidN

すべて試してみましたが、良い結果は得られませんでした。そのため、ipadを使用しているときに、すべての作業をsplitViewControllerメソッドに任せてbarButtonを無効にしました。

ポートレートの場合:

- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc { NSlog(@"portrait");}

横向きの場合:

- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem{ NSlog(@"landscape");}

これは常にロード時に機能します。

0
user1008139

これを試してください[[UIApplication sharedApplication] statusBarOrientation];

または、アプリデリゲートでこれを実装します

(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

できます

0
Sabby

問題は、_[UIDevice currentDevice]orientation]_が時々デバイスの向きを誤って報告することです。

代わりにUIInterfaceOrientationである_[[UIApplication sharedApplication]statusBarOrientation]_を使用するため、チェックするにはUIInterfaceOrientationIsLandscape(orientation)を使用する必要があります。

お役に立てれば。

0
iksnae

私はまだこの作業コードスニペットをiPhone 4で使用しています:

-(void)deviceOrientationDidChange:(NSNotification *)notification{

//Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    

int value = 0;

if(orientation == UIDeviceOrientationPortrait)
{
    value = 0;

}else if(orientation == UIDeviceOrientationLandscapeLeft)
{
    value = 90;

}else if(orientation == UIDeviceOrientationLandscapeRight)
{

    value = -90;

}

CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(value));
[photoImageView setTransform:cgCTM];

}

0
Rudolf Stepan

Swift 3 or 4。

`let orientation = UIApplication.shared.statusBarOrientation
 if orientation == .portrait {
        // portrait   
 } else if orientation == .landscapeRight || orientation == 
.landscapeLeft{
         // landscape     
 }`
0
Bilal Şimşek

これを試してください。それは私のために働いています。 didfinishedlaunchメソッドの当時は、デバイスの向きを検出できませんでした。デフォルトではポートレートとして使用します。そう。私は統計バーの向きを確認するために使用しています。このコードをテストします。 appdelegetのdidfinishedlaunchメソッドに入れます。

UIInterfaceOrientation orientation = [UIApplication sharedApplication] .statusBarOrientation;

if(orientation == 0) {//Default orientation
    //UI is in Default (Portrait) -- this is really a just a failsafe.

    NSLog("for portrait");


}else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{

    NSLog("portrait");
}else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{

    NSLog("Landscap");
}
0
jenish

これが本当の答えです。アプリが起動したとき、その向きは不明です。 shouldAutorotateToInterfaceOrientationおよびsupportedInterfaceOrientationsを使用して、選択する方向を決定します。

IPhone 5.0シミュレーターでサンプルアプリを起動し、以下のコードと「サポートされているインターフェイスの向き」を使用して、4つの可能な向きすべてを使用して回転させます。

20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)

私は多くのコードスニペットを見てきましたが、それらのどれも一般的に十分に動作しません(iPad&iPhone、iOS 5.0+)。

Try-this-try-thatを手探りする代わりに、ルートvcに以下を配置します。

#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {

#define ToNSString_VALUE(value) \
case value: return @#value

#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}

// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait);           // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft);      // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight);     // 4
ToNSString_END  (UIInterfaceOrientation);

// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown);               // 0
ToNSString_VALUE(UIDeviceOrientationPortrait);              // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown);    // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft);         // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight);        // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp);                // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown);              // 6
ToNSString_END  (UIDeviceOrientation);



// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
    NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
    return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}

// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
    static NSUInteger orientationsResult;

    if (!orientationsResult) {
        NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];

        for (id orientationString in supportedOrientations) {
            if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortrait;
                NSLog(@"Supported orientation: Portrait");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
                NSLog(@"Supported orientation: Portrait (upside-down)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
                NSLog(@"Supported orientation: Landscape (home button on the left)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
                NSLog(@"Supported orientation: Landscape (home button on the right)");
            } else {
                NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
            }
        }
    }
   return orientationsResult;
}

// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
    BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
    NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
    NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
    return result;
}

// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    NSString* orientationString;
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;

    if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
        orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
                             UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
                             UIInterfaceOrientationToNSString(interfaceOrientation)
                             ];
    } else {
        orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
                             ];
    }

    BOOL result = [self allowAutoRotate:interfaceOrientation];
    NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
          result ? "YES" : "NO",
          orientationString);
    return result;
}

現在の向きを使用しないセグエアニメーションの厄介な問題がまだあります。私の推測では、各VC=をサブクラス化し、Pushにプッシュ/デリゲートを通知するという方向性を置くことが、進むべき道だと思います。

また重要:

shouldAutorotateToInterfaceOrientationは機能しません

風景モードのtabBarControllerおよびnavigationControllers、エピソードII

0
user246672