Предотвратить вращение UIViewController, когда модальное вращение - PullRequest
0 голосов
/ 26 апреля 2018

Мое приложение в основном только для портрета. Так что ничего не вращается. Но не существует ОДНОГО исключения. Пользователь может добавлять фотографии, и при просмотре этих фотографий в полноэкранном режиме этот ViewController ДОЛЖЕН быть разрешен для поворота.

Поэтому я подумал, что если мой представляемый ViewController имеет supportedInterfaceOrientations return .portrait, а также shouldAutorotate return false, то этого должно быть достаточно, чтобы предотвратить его вращение?!?

Оказывается, что, когда я поворачиваюсь, пока отображается полноэкранное изображение, то и нижнее поворачивается.

Подведем итог:

RootViewController никогда не должен вращаться PresentedViewController может вращаться, но его вращение не должно вращаться RootViewController

Есть ли способ достичь этого?

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

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

Примерно так:

NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name:  Notification.Name("UIDeviceOrientationDidChangeNotification"), object: nil)

@objc func orientationChanged() {

if(UIDeviceOrientationIsLandscape(UIDevice.current.orientation)){

    print("landscape")
}

if(UIDeviceOrientationIsPortrait(UIDevice.current.orientation)){

    print("Portrait")
}

}

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

0 голосов
/ 26 апреля 2018

Попробуйте этот код ниже. Я следовал Этот урок , и он работает для меня. Что происходит:

Шаг 1. Предполагая, что внутри General ваш Device Orientation установлен на Portrait только:

Шаг 2. Код ниже, который вы добавляете внутрь AppDelegate, проходит через контроллеры навигации, а затем заглядывает внутрь своих контроллеров вида сверху. Если какой-либо из этих vcs имеет функцию с именем canRotate, то этот конкретный vc изменит ориентацию устройства с шага 1., вернув: return .allButUpsideDown

Добавьте эти 2 функции внизу вашего AppDelegate:

// add this first function
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

    // if the navigationController's root vc has a function inside of it named canRotate
    if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {

        if (rootViewController.responds(to: Selector(("canRotate")))) {
            // Unlock landscape view orientations for this view controller
            return .allButUpsideDown;
        }
    }

    // Only allow portrait (standard behaviour). vcs that don't contain a function with the name "canRotate" can't rotate and stay in portrait only
    return .portrait;
}

// add this second function
// loop through tabBarController or any navigationControllers
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
    if (rootViewController == nil) { return nil }
    if (rootViewController.isKind(of: UITabBarController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
    } else if (rootViewController.isKind(of: UINavigationController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
    } else if (rootViewController.presentedViewController != nil) {
        return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
    }
    return rootViewController
}

Шаг 3. Внутри модального vc вы должны добавить функцию с именем: @objc func canRotate(){}. Вам не нужно никуда звонить или добавлять что-либо внутри фигурных скобок. Код из шага 2 ищет эту функцию с именем canRotate. Если другие vcs не содержат функции с таким именем, они не могут вращаться.

Внутри модального viewController, который вы хотите вращать, добавьте функцию canRotate () в любом месте вне viewDidLoad и внутри viewWillDisappear добавьте код, чтобы вернуть все обратно к вашему обычному портрету:

override func viewDidLoad() {
        super.viewDidLoad()
}

@objc func canRotate(){}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // add this so once leaving this vc everything will go back to Portrait only
        if (self.isMovingFromParentViewController) {
            UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation")
        }
}
0 голосов
/ 26 апреля 2018

Вы можете дать исключение, как в AppDelegate:

//auto rotate
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        //landscape for perticular view controller
        let navigationController = window?.rootViewController as? UINavigationController
        if let activeController = navigationController?.visibleViewController {
            if activeController.isKind(of: VGVideoVC.self)  {//Pass your VC here
//                print("I have found my controller!")
                return UIInterfaceOrientationMask.all;
            }else{
                return UIInterfaceOrientationMask.portrait;
            }
        }else{
            return UIInterfaceOrientationMask.portrait;
        }
    }

А в остальной части ВК, где вы хотите, чтобы он был принудительно портретным, вы можете использовать так:

//MARK:- Screen Orientation

override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    return .portrait
}

override var shouldAutorotate: Bool{
    return true
}

Надеюсь, это поможет.

...