web-dev-qa-db-ja.com

iOS UIデバイスの向きの検出

デバイスが縦向きになっていることを検出して、特別なアニメーションを起動できるようにする必要があります。しかし、ビューを自動回転させたくありません。

デバイスが縦向きに回転したときに自動回転するビューをオーバーライドするにはどうすればよいですか?私のアプリは、ビューを横向きで表示するだけでよいのですが、縦向きへの回転を検出できるようにしたい場合も、縦向きをサポートする必要があるようです。

69
Jace999

アプリケーションがロードされるとき、またはビューがロードされるときに、次のことを試してください。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
   addObserver:self selector:@selector(orientationChanged:)
   name:UIDeviceOrientationDidChangeNotification
   object:[UIDevice currentDevice]];

次に、次のメソッドを追加します。

- (void) orientationChanged:(NSNotification *)note
{
   UIDevice * device = note.object;
   switch(device.orientation)
   {
       case UIDeviceOrientationPortrait:
       /* start special animation */
       break;

       case UIDeviceOrientationPortraitUpsideDown:
       /* start special animation */
       break;

       default:
       break;
   };
}

上記により、ビューの自動回転を有効にせずに、デバイスの向きの変更を登録できます。


注意

IOSのすべての場合において、オブザーバーを追加するときは、適切なタイミングで(常にではありませんが、ビューが表示/非表示になったときに)オブザーバーも削除します。監視/非監視コードの「ペア」のみを持つことができます。これを行わないと、アプリがクラッシュします。観察/非観察の場所を選択することは、このQAの範囲外です。ただし、上記の「observe」コードに一致する「unobserve」が必要です。

170
David M. Syzdek

向きの変化を検出する方法を探してこの質問に来た場合(必ずしも回転を無効にしたくない場合)、iOS 8から利用可能な viewWillTransitionToSize にも注意する必要があります。 。

here のSwiftの例

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            println("Portrait")
            // Do something
        default:
            println("Anything But Portrait")
            // Do something else
        }

        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            println("rotation completed")
    })

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

そして、実際の向きについて心配する必要がない場合:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    // do something

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

here のObjective-Cの例

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{   
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
        // do whatever
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    { 

    }];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

そして、実際の方向について心配する必要がない場合( this answer から取得):

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Do view manipulation here.
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

こちらもご覧ください

17
Suragch

1)Swift Davidの回答のバージョン2)方向の変更がない場合でも方向を検出したい場合(Moeの回答のSwift vesion iOSのデバイス?

    // Initial device orientation
    let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
    if(orientation == UIInterfaceOrientation.Unknown){
        // code for Unknown
    }
    else if(orientation == UIInterfaceOrientation.Portrait){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.LandscapeRight){
        // code for Landscape        
    }
    else if(orientation == UIInterfaceOrientation.LandscapeLeft){
        // ode for Landscape
    }

    // To detect device orientation change
    UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "orientationChanged:",
        name: UIDeviceOrientationDidChangeNotification,
        object: UIDevice.currentDevice())

orientationChanged関数

func orientationChanged(note: NSNotification)
{
    let device: UIDevice = note.object as! UIDevice
    switch(device.orientation)
    {
        case UIDeviceOrientation.Portrait:
        // code for Portrait
        break
        case UIDeviceOrientation.PortraitUpsideDown:
        // code for Portrait
        break
        case UIDeviceOrientation.LandscapeLeft:
        // code for Landscape
        break
        case UIDeviceOrientation.LandscapeRight:
        // code for Landscape
        break
        case UIDeviceOrientation.Unknown:
        // code for Unknown
        break
        default:
        break
    }
}
3

私があなたを正しく理解していれば、あなたのアプリは横向きだけです。アプリの設定で、ランドスケープのみであるため、回転を心配する必要がないことを指定できます。アプリは横向きで起動し、iPadの向きに関係なくそこに留まります。

1
drekka

デバイスオブジェクトを作成したくない場合は、使用することもできます

-(void) seObserverForOrientationChanging
{
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(orientationChanged:)
     name:UIDeviceOrientationDidChangeNotification
     object:[UIDevice currentDevice]];
}


- (void) orientationChanged:(NSNotification *)note
{
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
        //Do something in landscape
    }
    else {
        //Do something in portrait
    }
}
0
B.Kosmowski

.UIDeviceOrientationDidChange通知は、デバイスが回転していなくても、iPhoneで何度も呼び出されます。理由はわかりませんが、デバイスが実際に回転したときにのみ必要な場合は、次を実行します。

NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)

オブザーバーから呼び出されるメソッドは次のようになります。

func orientationChanged() {

    if traitCollection.isIphone {

        defer {
            self.previousTraitCollectionForIphone = traitCollection
        }

        guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {

            updateView()
            return
        }

        if previousTraitCollectionForIphone != traitCollection {
            updateView()
        }

    } else {
        updateView()
    }
}

まず、必要な向き以外をすべて無効にします(回転しないように)

次に、デビッドが言ったように、デバイスの現在の向きを取得します。

https://developer.Apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html

あるいは、自分で加速度計を使用して(とにかくその方法が行われるため)、重力がどこにあるかを確認して、その方向を確認することができます。このアプローチをとると、自分で値をいじってさまざまな結果を得ることができます。

0
Pochi