“InterfaceOrientation” застаріло в iOS 8, Як змінити цей метод Завдання C.


75

Я завантажив вигляд simpleCamera з Cocoa Controls, який використовує цей метод

- (AVCaptureVideoOrientation)orientationForConnection
{
    AVCaptureVideoOrientation videoOrientation = AVCaptureVideoOrientationPortrait;
    switch (self.interfaceOrientation) {
        case UIInterfaceOrientationLandscapeLeft:
            videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
            break;
        case UIInterfaceOrientationLandscapeRight:
            videoOrientation = AVCaptureVideoOrientationLandscapeRight;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
            break;
        default:
            videoOrientation = AVCaptureVideoOrientationPortrait;
            break;
    }
    return videoOrientation;
}

проблема полягає в тому, що "interfaceOrientation" застаріла в iOS 8, але я не знаю, чим і як замінити це в стані Switch.


Відповіді:


145

Орієнтація пристрою неправильна. Наприклад, пристрій може перебувати в альбомному режимі, але контролер перегляду, який підтримує лише портрет, залишатиметься в книжковому режимі.

Натомість використовуйте це:

[[UIApplication sharedApplication] statusBarOrientation]

Ще одним бонусом є те, що він все ще використовує перелік UIInterfaceOrientation, тому дуже мало вашого коду потрібно змінити.


9
statusBarOrientationзастаріло в iOS 9 - developer.apple.com/documentation/uikit/uiapplication/…
Pang

21

Починаючи з iOS8, Apple рекомендує використовувати TraitCollections (Класи розмірів) замість interfaceOrientation.

Більше того, оскільки iOS 9 та нова функція iPad «Багатозадачність», є деякі випадки, коли орієнтація пристрою не відповідає пропорціям вікна! (злом інтерфейсу програми)

Тому ви також повинні бути дуже обережними при використанні класів звичайного розміру, оскільки не потрібно займати весь екран iPad.

Іноді TraitCollections не задовольняє всіх ваших потреб у дизайні. У цих випадках Apple рекомендує порівняти межі подання:

if view.bounds.size.width > view.bounds.size.height {
    // ...
}

Я був дуже здивований, але ви можете перевірити на відео WWDC 2015 Початок роботи з багатозадачністю на iPad в iOS 9 о 21:15.

Можливо, ви справді шукаєте орієнтацію пристрою, а не пропорції екрану чи вікна. Якщо ви дбаєте про камеру пристрою, вам не слід використовувати TraitCollection, а також межі перегляду.


Дійсно, це згадується. Дякую!!
Ankish Jain

Чи є рекомендований спосіб дізнатись, чи пристрій горизонтальний лівий чи правий? Це насправді має значення для вирізу iPhone X :(
Павло Алексєєв

Ну, ви можете використовувати, [[UIDevice currentDevice] orientation]якщо хочете перевірити реальну орієнтацію пристрою, але не слід використовувати його для адаптації iPhone X. Будь ласка, використовуйте нову безпечну зону iOS 11 або старе поле макета.
vmeyer

3

Свіфт версії 4+

UIApplication.shared.statusBarOrientation

1
В iOS 13 цей метод надає "" статусBarOrientation 'застарілий: спочатку застарілий у iOS 13.0 - Замість цього використовуйте властивість interfaceOrientation. " повідомлення
Пітер Джонсон

2

Використання -orientationвластивості UIDevice є неправильним (навіть якщо це могло працювати в більшості випадків) і може призвести до деяких помилок, наприклад, UIDeviceOrientationвраховуйте також орієнтацію пристрою, якщо він знаходиться лицьовою стороною вгору або вниз, у UIInterfaceOrientationenum немає пари для тих, хто значення.
Крім того, якщо ви заблокуєте програму в певній орієнтації, UIDevice надасть вам орієнтацію пристрою, не враховуючи це.
З іншого боку, iOS8 застаріла interfaceOrientationвластивість UIViewControllerкласу.
Для виявлення орієнтації інтерфейсу доступні 2 варіанти:

  • Використовуйте орієнтацію в рядку стану
  • Використовуйте класи розміру, на iPhone, якщо вони не замінені, вони можуть дати вам спосіб зрозуміти поточну орієнтацію інтерфейсу

Все ще бракує способу зрозуміти напрямок зміни орієнтації інтерфейсу, що дуже важливо під час анімації.
У сесії WWDC 2014 «Переглянути вдосконалення контролера в iOS8» спікер також пропонує рішення цієї проблеми, використовуючи метод, який замінює -will/DidRotateToInterfaceOrientation.

Тут пропоноване рішення частково реалізоване:

-(void) viewWillTransitionToSize:(CGSize)s withTransitionCoordinator:(UIVCTC)t {
    orientation = [self orientationFromTransform: [t targetTransform]]; 
    oldOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 
    [self myWillRotateToInterfaceOrientation:orientation duration: duration]; 
    [t animateAlongsideTransition:^(id <UIVCTCContext>) {
         [self myWillAnimateRotationToInterfaceOrientation:orientation
                                                  duration:duration];
      }
      completion: ^(id <UIVCTCContext>) {
         [self myDidAnimateFromInterfaceOrientation:oldOrientation];
      }];
}

як метод originFromTransform: метод виводить орієнтацію з перетворення?
Чандра


0

Коли ви використовуєте UIApplication.shared.statusBarOrientation, Xcode 11 покаже попередження'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.

Ця відповідь наведена у версії Swift 5 та підтримує версії iOS 13 та старіші. Він передбачає наступне:

  • Ви створите лише одну сцену, і ніколи не одну
  • Ви хочете додати свій код до певного подання
  • У вас є подання, яке містить змінну previewLayerтипу типуAVCaptureVideoPreviewLayer

Спочатку у свій SceneDelegate.swiftдодайте такі рядки:

    static var lastCreatedScene: UIWindowScene?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let newScene = (scene as? UIWindowScene) else { return }
        Self.lastCreatedScene = newScene
    }

Потім у своєму поданні додайте таку функцію та викликайте її layoutSubviews():

    func refreshOrientation() {
        let videoOrientation: AVCaptureVideoOrientation
        let statusBarOrientation: UIInterfaceOrientation
        if #available(iOS 13, *) {
            statusBarOrientation = SceneDelegate.lastCreatedScene?.interfaceOrientation ?? .portrait
        } else {
            statusBarOrientation = UIApplication.shared.statusBarOrientation
        }
        switch statusBarOrientation {
        case .unknown:
            videoOrientation = .portrait
        case .portrait:
            videoOrientation = .portrait
        case .portraitUpsideDown:
            videoOrientation = .portraitUpsideDown
        case .landscapeLeft:
            videoOrientation = .landscapeLeft
        case .landscapeRight:
            videoOrientation = .landscapeRight
        @unknown default:
            videoOrientation = .portrait
        }
        self.previewLayer.connection?.videoOrientation = videoOrientation
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.