Настройка ориентации устройства в Swift iOS

Я работаю над быстрым приложением для iPhone. В моем приложении есть модальный вид, который я хочу видеть только в портретном режиме.

Мой вопрос: как программно заставить телефон не разрешать поворот? Другими словами, я ищу код, который не позволит отображать модальный вид в ландшафтном режиме (включение блокировки вертикального вращения).

Это всего лишь 1 модальный вид, поэтому я не могу отключить ротацию для всего приложения, иначе я просто отключил бы вращение вообще.

Я нашел код в своем исследовании здесь Но это в объективе C, в случае, если это помогает. Спасибо!

Ответ 1

Вы можете вставить эти методы в ViewController каждого представления, которое должно быть портретом:

override func shouldAutorotate() -> Bool {
    return false
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

Ответ 2

Привет для LandscapeLeft и LandscapeRight (Update Swift 2.0)

enter image description here И у вас есть это в информации

enter image description here

И UIController

override func shouldAutorotate() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return [UIInterfaceOrientationMask.LandscapeLeft,UIInterfaceOrientationMask.LandscapeRight]
}

Для PortraitUpsideDown и Portrait используйте это enter image description here

override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return false
    }
    else {
        return true
    }
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return [UIInterfaceOrientationMask.Portrait ,UIInterfaceOrientationMask.PortraitUpsideDown]
}

Сообщение из Франции, с Рождеством!

Изменить:

Другое решение:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        if visibleViewController is MyViewController {
            return true   // rotation
        } else {
            return false  // no rotation
        }
    }

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return (visibleViewController?.supportedInterfaceOrientations())!
    }
}

Ответ 3

Swift 3

Ориентация вращения сложнее, если контроллер представления встроен в UINavigationController или UITabBarController, контроллер навигации или панели вкладок имеет приоритет и принимает решения по авторотации и поддерживаемой ориентации.

Используйте следующие расширения в UINavigationController и UITabBarController, чтобы контроллеры представлений, встроенные в один из этих контроллеров, принимали решения:

Расширение UINavigationController

extension UINavigationController {

override open var shouldAutorotate: Bool {
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.preferredInterfaceOrientationForPresentation
        }
        return super.preferredInterfaceOrientationForPresentation
    }
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }
 }}

Расширение UITabBarController

extension UITabBarController {

override open var shouldAutorotate: Bool {
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.preferredInterfaceOrientationForPresentation
        }
        return super.preferredInterfaceOrientationForPresentation
    }
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }
}}

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

Блокировка для конкретной ориентации

class YourViewController: UIViewController {
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        return .portrait
    }
}}

Отключить вращение

    class YourViewController: UIViewController {
open override var shouldAutorotate: Bool {
    get {
        return false
    }
}}

Изменить предпочтительную ориентацию интерфейса для презентации

class YourViewController: UIViewController {
open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        return .portrait
    }
}}

Ответ 4

Выше код может не работать из-за возможности, если ваш контроллер просмотра принадлежит контроллеру навигации. Если да, то он должен подчиняться правилам навигационного контроллера, даже если он имеет разные правила ориентации. Лучшим подходом было бы позволить контроллеру представления решить сам, и контроллер навигации будет использовать решение верхнего контроллера.

Мы можем поддерживать как фиксацию в текущей ориентации, так и авторотирование для блокировки определенной ориентации с помощью этого общего расширения на UINavigationController: -:

extension UINavigationController {
            public override func shouldAutorotate() -> Bool {
                return visibleViewController.shouldAutorotate()
            }

        public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
            return (visibleViewController?.supportedInterfaceOrientations())!
        }
    }

Теперь в вашем контроллере просмотра мы можем

class ViewController: UIViewController {
    // MARK: Autoroate configuration

    override func shouldAutorotate() -> Bool {
        if (UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait ||
            UIDevice.currentDevice().orientation == UIDeviceOrientation.PortraitUpsideDown ||
            UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
                return true
        }
        else {
            return false
        }
    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue) | Int(UIInterfaceOrientationMask.PortraitUpsideDown.rawValue)
    }
}

Надеюсь, это поможет. Благодаря

Ответ 5

Это отключит авторотацию представления:

override func shouldAutorotate() -> Bool {
    return false;
}

Обновление

override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return false;
    }
    else {
        return true;
    }
}

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

Ответ 6

Если кто-то хочет ответа, я думаю, что я его получил. Попробуйте следующее:

  • Перейдите в свой файл .plist и проверьте все ориентации.
  • В контроллере представления вы хотите принудительно настроить ориентацию, добавьте следующий код:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait.toRaw().hashValue | UIInterfaceOrientationMask.PortraitUpsideDown.toRaw().hashValue
}

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

EDIT:

Для принудительного вращения используйте следующий код:

let value = UIInterfaceOrientation.LandscapeRight.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

Он работает для iOS 7 и 8!

Ответ 7

enter image description here

Go to your pList and add or remove the following as per your requirement:

"Supported Interface Orientations" - Array
"Portrait (bottom home button)" - String
"Portrait (top home button)" - String
"Supported Interface Orientations (iPad)" - Array
"Portrait (bottom home button)" - String
"Portrait (top home button)" - String
"Landscape (left home button)" - String
"Landscape (right home button)" - String

Примечание. Этот метод позволяет вращаться для всего приложения.

ИЛИ

Создайте ParentViewController для UIViewControllers в проекте (метод наследования).

//  UIappViewController.swift

import UIKit

class UIappViewController: UIViewController {
          super.viewDidLoad()   
    }
//Making methods to lock Device orientation.
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
    override func shouldAutorotate() -> Bool {
        return false
    }                                                                                                                                       
    override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

Свяжите каждый контроллер контроллера представления как UIappViewController.

//  LoginViewController.swift

import UIKit
import Foundation

class LoginViewController: UIappViewController{

    override func viewDidLoad()
    {
        super.viewDidLoad()

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

Ответ 8

Для Swift 3, iOS 10

override open var shouldAutorotate: Bool {
    return false
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return .portrait
}

Однако ошибка с настройкой shouldAutorotate в настоящее время не работает на iOS 9.

Ответ 9

В файле info.plist измените ориентацию, которую вы хотите в "поддерживаемой ориентации интерфейса".

В быстром режиме поддерживаются файлы- > info.plist- > , поддерживающие ориентацию интерфейса.

Ответ 10

Я боролся все утро, чтобы получить ТОЛЬКО ландшафт влево/вправо, поддерживаемый должным образом. Я обнаружил что-то действительно раздражающее; хотя вкладка "Общие" позволяет отменить выбор "Портрет" для ориентации устройства, вы должны отредактировать сам слой, чтобы отключить ориентацию ориентации портрета и PortraitUpsideDown INTERFACE - это последний ключ в plist: "Поддерживаемые ориентации интерфейса".

Другое дело в том, что, кажется, вы должны использовать "маскирующие" версии перечислений (например, UIInterfaceOrientationMask.LandscapeLeft), а не только ориентационную. Код, который заставил его работать для меня (в моем главном viewController):

override func shouldAutorotate() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue) | Int(UIInterfaceOrientationMask.LandscapeRight.rawValue)
}

Создание этой комбинации изменений plist и кода - единственный способ, которым я смог заставить его работать должным образом.

Ответ 11

Более быстрая версия:

override func shouldAutorotate() -> Bool {
    switch UIDevice.currentDevice().orientation {
    case .Portrait, .PortraitUpsideDown, .Unknown:
        return true
    default:
        return false
    }
}

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.Portrait.rawValue) | Int(UIInterfaceOrientationMask.PortraitUpsideDown.rawValue)
}

UINavigationController от Вивека Парихара

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

Ответ 12

//Swift 2

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    let orientation: UIInterfaceOrientationMask =
    [UIInterfaceOrientationMask.Portrait, UIInterfaceOrientationMask.PortraitUpsideDown]
    return orientation
}

Ответ 13

Два предложения с решением @Vivek Parihar:

  • Если мы представляем какой-либо viewController, мы должны проверить nil для "visibleViewController" в расширении navigationController

    extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        var shouldAutorotate = false
        if visibleViewController != nil {
            shouldAutorotate = visibleViewController.shouldAutorotate()
        }
        return shouldAutorotate
    }
    
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    }
    
  • Если мы используем любой файл действий для представления, и пользователь будет вращаться вверху, ваш лист действий откроется с верхнего края экрана: P, чтобы решить эту проблему, мы должны взять только портрет

    override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return true
    }
    else {
        return false
    }
    

    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    }
    

Ответ 14

Swift 2.2

    func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {

    if self.window?.rootViewController?.presentedViewController is SignatureLandscapeViewController {

        let secondController = self.window!.rootViewController!.presentedViewController as! SignatureLandscapeViewController

        if secondController.isPresented {

            return UIInterfaceOrientationMask.LandscapeLeft;

        } else {

            return UIInterfaceOrientationMask.Portrait;
        }

    } else {

        return UIInterfaceOrientationMask.Portrait;
    }
}

Ответ 15

Мой скромный вклад (Xcode 8, Swift 3):

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {
            if (rootViewController.responds(to: Selector(("canRotate")))) {
                // Unlock landscape view orientations for this view controller
                return .allButUpsideDown;
            }
        }
        return .portrait;        
    }

    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
    }

... на AppDelegate. Все кредиты для Gandhi Mena: http://www.jairobjunior.com/blog/2016/03/05/how-to-rotate-only-one-view-controller-to-landscape-in-ios-slash-swift/

Ответ 16

Из ios 10.0 нам нужно set { self.orientations = newValue } для настройки ориентации, убедитесь, что в вашем проекте включено свойство ландшафта.

private var orientations = UIInterfaceOrientationMask.landscapeLeft
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self.orientations }
    set { self.orientations = newValue }
}

Ответ 17

Swift 4:

Самый простой ответ, в моем случае, чтобы убедиться, что один просмотр учебника на борту был только портретным:

extension myViewController {
    //manage rotation for this viewcontroller
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}

Eezy-peezy.