Обнаружение ориентации iOS UIDevice

Мне нужно определить, когда устройство находится в портретной ориентации, чтобы я мог отключить специальную анимацию. Но я не хочу, чтобы мой взгляд на авторотацию.

Как переопределить авторотирование вида, когда устройство повернуто к портрету? Моему приложению нужно только отображать его в ландшафте, но мне кажется, что мне нужно поддерживать портрет также, если я хочу, чтобы можно было обнаружить поворот к портрету.

Ответ 1

Попробуйте выполнить следующее при загрузке приложения или при загрузке вашего представления:

[[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. Однако вы должны иметь "unobserve", чтобы соответствовать "наблюдаемому" коду выше.

Ответ 2

Если вы пришли к этому вопросу в поисках того, как определить изменение ориентации (не обязательно желая отключить поворот), вы также должны знать viewWillTransitionToSize, который доступен в iOS 8.

Пример 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)
}

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];
}

И если вам не нужно беспокоиться о фактической ориентации (взятой из этого ответа):

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

См. также

Ответ 3

1) Быстрая версия ответа Дэвида 2) Если вы все еще хотите определить ориентацию, когда нет изменения ориентации (Swift vesion of Moe отвечает Как определить ориентацию устройства на 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 function

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
    }
}

Ответ 4

Если вы правильно поняли, ваше приложение будет только ландшафтом. Вы можете просто указать в настройках приложений, что это только пейзаж, и поэтому не нужно беспокоиться о вращении. Приложение запустится в пейзаже и останется там независимо от того, как ориентируется iPad.

Ответ 5

Сначала отключите все, кроме нужной ориентации (чтобы она не вращалась)

Тогда, как сказал Дэвид, просто введите текущую ориентацию устройства:

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

В качестве альтернативы вы можете просто использовать акселерометр самостоятельно (так как все равно это делается) и проверьте, где находится сила тяжести, чтобы увидеть, какую ориентацию она имеет. Если вы примете такой подход, вы можете сами играть со значениями, чтобы получить разные результаты.

Ответ 6

Если вы не хотите создавать объект устройства, вы также можете использовать

-(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
    }
}

Ответ 7

.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()
    }
}