Программная блокировка ориентации iDevice

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

//MARK:- ORIENTATION
func changeOrientation(orientation: String) {
    switch orientation {
    case "Portrait":
        UserDefaults.standard.set("Portrait", forKey: UserDefaultsKeys.preferredOrientation)
        appDelegate.preferredOrientation = "Portrait"
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        break
    case "Landscape":
        UserDefaults.standard.set("Landscape", forKey: UserDefaultsKeys.preferredOrientation)
        appDelegate.preferredOrientation = "Landscape"
        let value = UIInterfaceOrientation.landscapeLeft.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        break
    default:
        UserDefaults.standard.set("Both", forKey: UserDefaultsKeys.preferredOrientation)
        appDelegate.preferredOrientation = "Both"
        break
    }
    /*not necessary*/
    let vc = UIViewController()
    UIViewController.attemptRotationToDeviceOrientation()//forces to rotate
    /*not necessary*/
    self.present(vc, animated: false, completion: nil)
    UIView.animate(withDuration: 0.3, animations: {
        vc.dismiss(animated: false, completion: nil)
    })
    /*not necessary*/
}

open override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        switch appDelegate.preferredOrientation {
        case "Portrait":
            return .portrait
        case "Landscape":
            return .landscape
        default:
            return .all
        }
    }
}

open override var shouldAutorotate: Bool {
    get {
        return true
    }
}

Однако если я выберу "Пейзаж" в портретном режиме, он автоматически переключится в ландшафтный режим. Но если я поверну устройство обратно в портретное положение, оно также будет работать (что не должно работать в соответствии с требованиями). Требование аналогично тому, что происходит, когда мы настраиваем проект только в портретном режиме, и как он будет себя вести, когда устройство поворачивается в ландшафтный режим.

1 ответ

Решение

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

UIViewController.attemptRotationToDeviceOrientation()

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

    class ViewController: UIViewController {

    enum Orientation {
        case Landscape
        case Portrait

        mutating func changeOrientation() {
            if self == .Portrait {
                self = .Landscape
            }
            else {
                self = .Portrait
            }
        }

        func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
            switch self {
            case .Landscape:
                return .Landscape
            case .Portrait:
                return .Portrait
            }
        }

        func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
            switch self {
            case .Landscape:
                return UIInterfaceOrientation.LandscapeLeft
            case .Portrait:
                return .Portrait
            }
        }
    }

    var currentOrientation: Orientation = .Portrait

    //    Returns a Boolean value indicating whether the view controller's contents should auto rotate.
    override func shouldAutorotate() -> Bool {
        return true
    }

//    Returns all of the interface orientations that the view controller supports.
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return currentOrientation.supportedInterfaceOrientations() //UIInterfaceOrientationMask.All
    }

//    Returns the interface orientation to use when presenting the view controller.
    override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
        return UIInterfaceOrientation.Portrait
    }

    @IBAction func forceChangeOrientations(sender: AnyObject) {
        self.currentOrientation.changeOrientation()

        let value = self.currentOrientation.preferredInterfaceOrientationForPresentation().rawValue
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
        UIViewController.attemptRotationToDeviceOrientation()
    }

}
Другие вопросы по тегам