Как заставить устройство iOS определять его ориентацию с помощью гироскопа? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть ситуация, когда мое приложение иногда заставляет определенные контроллеры представления появляться в определенной ориентации.

Единственный способ сделать это - вручную установить ориентацию устройства и указать приложению попытаться повернуть себя так:

switch (forceOrientation){
    case Orientations.PORTRAIT:
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        UIViewController.attemptRotationToDeviceOrientation()
    case Orientations.LANDSCAPE:
        let value = UIInterfaceOrientation.landscapeLeft.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        UIViewController.attemptRotationToDeviceOrientation()
    default:
        break
}

Это работает просто отлично. Однако, как только я закрываю этот контроллер вида и возвращаюсь к предыдущему, я все еще нахожусь в принудительной ориентации независимо от того, как устройство удерживается. Есть ли способ установить значение ориентации на «грязный» или что-то в этом роде и автоматически определить его?

Я попытался установить значение ориентации на UIInterfaceOrientation.unknown.rawValue и затем попытаться повернуть, но это не работает.

Я использую Swift 4.1

- Правка -

Чтобы уточнить, что я делаю, немного больше:

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

public override var shouldAutorotate: Bool{
    return allowOrientationChange // this is set at some point after initializing
}

public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return orientationMask // this defaults to orientationMaskAll but is overridden 
}

При закрытии контроллера представления предыдущий корневой контроллер добавляется обратно в качестве корневого. (Но он все равно поворачивается к тому, что было принудительно, и не обновляется, пока вы не переместите устройство)

1 Ответ

0 голосов
/ 04 сентября 2018

Вы можете переопределить var supportedInterfaceOrientations: UIInterfaceOrientationMask { get } и настроить его так, чтобы он возвращал доступные ориентации, которые вы хотите в любой момент времени.

По сути, это свойство возвращает переменную, которая коррелирует с вашим forceOrientation перечислением.

Подробнее см. https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations.

Чтобы вызвать вращение, вы можете сделать:

let previousOrientation = UIDevice.current.orientation  
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
//Rotates all view controllers
UIViewController.attemptRotationToDeviceOrientation()

//Find all UIViewControllers that need to be locked,  I recommend using a protocol


guard let appDelegate = UIApplication.sharedApplication().delegate, 
      let window = appDelegate.window, 
      let root = window.rootViewController,


else{
    fatalError("error")
} 
var viewControllers : [UIViewController] = []()
if root.presentedViewController != nil {
    viewControllers += [root.presentedViewController]
}
viewControllers += root.children
viewControllers.filter{$0 as OrientationLocked}.forEach{ vc in
  vc.orientationMask = ... //whatever previousOrientation isn't
}

//undo rotation
UIDevice.current.setValue(previousOrientation, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

//View controllers that had been filtered are now rotated, where as anything underneath were treated as if a rotation did not happen

... любой контроллер представления, который может быть заблокирован, нуждается в этом протоколе

protocol OrientationLocked {
    var orientationMask : UIInterfaceOrientationMask 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...