Jak wykryć zmianę orientacji?

148

Używam Swift i chcę mieć możliwość załadowania kontrolera UIViewController po obróceniu do poziomu. Czy ktoś może wskazać mi właściwy kierunek?

Nie mogę znaleźć niczego w Internecie i jestem trochę zdezorientowany dokumentacją.

David
źródło
1
Przypuszczam, że API się nie zmieniło, więc powinno to być "didRotateToOrientation" i "willRotateToOrientation", coś w tym rodzaju, spójrz na dokumentację Apple
David 'mArm' Ansermot
1
Cześć @ mArm.ch, dzięki za szybką odpowiedź! Więc jak bym to zaimplementował? (To moja pierwsza aplikacja ... Jestem bardzo nowy w IOS) :)
David
Przesłałem ponownie jako odpowiedź, dla innych ludzi. Czy możesz to zaakceptować, jeśli ci to odpowiada?
David 'mArm' Ansermot

Odpowiedzi:

194

Oto jak to działa:

W AppDelegate.swiftwewnątrz didFinishLaunchingWithOptions funkcji I umieścić:

NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)

a następnie w klasie AppDelegate umieściłem następującą funkcję:

func rotated() {
    if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
        print("Landscape")
    }

    if UIDeviceOrientationIsPortrait(UIDevice.current.orientation) {
        print("Portrait")
    }
}

Mam nadzieję, że to pomoże komukolwiek innemu!

Dzięki!

David
źródło
5
Próbowałem dodać addObserver w AppDelegate, ale nadal otrzymywałem SIGABRT w CoreFoundation z nierozpoznanym selektorem. Jednak kiedy przeniosłem addObserver do viewDidLoad w moim pierwszym widoku, działało idealnie. Tylko dla informacji, jeśli ktoś napotka ten sam problem.
FractalDoctor
1
Jestem nowy w kodowaniu, ale nie powinienem selectormieć formatu ciągu znaków "rotated:"??
Chameleon
4
Jestem całkiem pewien, że to tylko wtedy, gdy akceptujesz argumenty (co rotated()nie jest)
David
26
Uważaj, bo UIDeviceOrientationto coś innego niż UIInterfaceOrientation... Wynika to z faktu, że UIDeviceOrientationwykrywa również orientacje zakryte i odkryte, co oznacza, że ​​kod może losowo przeskakiwać między portretem a krajobrazem, jeśli urządzenie spoczywa na prawie płaskiej, ale nieco nierównej powierzchni (np. Kołysze się na wystającej kamera z
6/6
4
Ta metoda NIE DZIAŁA, jeśli telefon wyłączył automatyczne obracanie.
chengsam,
178
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        print("Landscape")
    }
    if UIDevice.current.orientation.isFlat {
        print("Flat")
    } else {
        print("Portrait")
    }
}
Mirosław Święcicki
źródło
71
Będzie to nazwane PRZED rotacją. Jeśli potrzebujesz np. Rozmiaru ramy po obróceniu to rozwiązanie nie zadziała.
Zagłosuj za
nie działał w rozszerzeniu. pozioma lub pionowa nadal drukowana „prosto”
TomSawyer
4
Ta metoda NIE DZIAŁA, jeśli telefon wyłączył automatyczne obracanie.
chengsam,
5
na iPadzie, ponieważ klasa rozmiaru jest taka sama, zarówno dla orientacji poziomej, jak i pionowej, ta metoda nigdy nie jest wywoływana.
Jacky
To również się nie powiedzie, jeśli urządzenie zwróci isFlat. developer.apple.com/documentation/uikit/uideviceorientation/…
CodeBender
57

Muszę wykryć obrót podczas używania aparatu z AVFoundationi okazało się, że didRotate( obecnie przestarzałe ) & willTransitionmetody były zawodne dla moich potrzeb. Korzystanie z powiadomienia wysłanego przez Davida zadziałało, ale nie jest aktualne dla Swift 3.x / 4.x.

Swift 4.2 Nazwa powiadomienia została zmieniona.

Wartość zamknięcia pozostaje taka sama jak w Swift 4.0:

var didRotate: (Notification) -> Void = { notification in
        switch UIDevice.current.orientation {
        case .landscapeLeft, .landscapeRight:
            print("landscape")
        case .portrait, .portraitUpsideDown:
            print("Portrait")
        default:
            print("other")
        }
    }

Aby skonfigurować powiadomienie dla Swift 4.2 :

NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification,
                                       object: nil,
                                       queue: .main,
                                       using: didRotate)

Aby usunąć powiadomienie dla Swift 4.2 :

NotificationCenter.default.removeObserver(self,
                                          name: UIDevice.orientationDidChangeNotification,
                                          object: nil)

Jeśli chodzi o oświadczenie o wycofaniu , mój pierwszy komentarz był mylący, więc chciałem to zaktualizować. Jak wspomniano, użycie @objcwnioskowania zostało przestarzałe, co z kolei było potrzebne do korzystania z pliku #selector. Używając zamiast tego zamknięcia, można tego uniknąć i masz teraz rozwiązanie, które powinno uniknąć awarii z powodu wywołania nieprawidłowego selektora.

Wszystko poniżej jest przestarzałe od XCode 10 i iOS 4.2

Swift 4.0 Dzięki Swift 4.0 firma Apple zachęca nas do unikania korzystania z #selector, więc to podejście wykorzystuje teraz blok uzupełniania. To podejście jest również wstecznie kompatybilne ze Swift 3.x i byłoby zalecanym podejściem w przyszłości.

To jest ostrzeżenie kompilatora, które otrzymasz w projekcie Swift 4.x, jeśli użyjesz #selectorfunkcji z powodu wycofania @objcwnioskowania:

wprowadź opis obrazu tutaj

Wejście w szybką ewolucję tej zmiany .

Skonfiguruj wywołanie zwrotne:

// If you do not use the notification var in your callback, 
// you can safely replace it with _
    var didRotate: (Notification) -> Void = { notification in
        switch UIDevice.current.orientation {
        case .landscapeLeft, .landscapeRight:
            print("landscape")
        case .portrait, .portraitUpsideDown:
            print("Portrait")
        default:
            print("other")
        }
    }

Skonfiguruj powiadomienie:

NotificationCenter.default.addObserver(forName: .UIDeviceOrientationDidChange,
                                       object: nil,
                                       queue: .main,
                                       using: didRotate)

Zburz to:

NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
CodeBender
źródło
4
Czy masz odniesienie do tego, gdzie Apple mówi o zniechęcaniu do korzystania z #selector w Swift 4? Chciałbym przeczytać, dlaczego to mówią.
jeffjv
@jeffjv Oczywiście nie mam bezpośredniego linku do dokumentu Apple, ale zamieściłem zrzut ekranu z ostrzeżeniem kompilatora, które XCode zapewnia, jeśli używasz poprzedniego podejścia.
CodeBender,
1
Dodałem link do szybkiej ewolucji, który omawia zmianę.
CodeBender,
1
@CodeBender: Ostrzeżenie kompilatora nie oznacza tego, co sugerujesz. #selector nie jest amortyzowany, tylko wnioskowanie „@objc”. Oznacza to, że gdy używasz funkcji jako #selektora, musisz ją jawnie oznaczyć, aby kompilator wygenerował dodatkowy poprawny kod, ponieważ kompilator nie będzie już próbował wywnioskować go z twojego użycia. Dlatego jeśli dodasz „@obj” do swojej funkcji rotate () w rozwiązaniu Swift 3.0, kod skompiluje się bez ostrzeżenia.
Mythlandia
Dzięki @Mythlandia, zaktualizowałem odpowiedź, aby rozwiązać problem z moim początkowym stwierdzeniem.
CodeBender,
19

Używanie -orientationwłaściwości of UIDevicenie jest poprawne (nawet jeśli mogłoby działać w większości przypadków) i może prowadzić do pewnych błędów, na przykład weź UIDeviceOrientationpod uwagę także orientację urządzenia, jeśli jest ono odkryte lub w dół, nie ma bezpośredniej pary w UIInterfaceOrientationwyliczeniu dla tych wartości.
Ponadto, jeśli zablokujesz aplikację w określonej orientacji, UIDevice poda orientację urządzenia bez uwzględnienia tego.
Z drugiej strony iOS8 wycofał interfaceOrientationwłaściwość UIViewControllerklasy.
Dostępne są 2 opcje wykrywania orientacji interfejsu:

  • Użyj orientacji paska stanu
  • Użyj klas rozmiarów, na iPhonie, jeśli nie zostaną zastąpione, mogą dać ci sposób na zrozumienie bieżącej orientacji interfejsu

Brakuje jeszcze sposobu zrozumienia kierunku zmiany orientacji interfejsu, co jest bardzo ważne podczas animacji.
W sesji WWDC 2014 „Zobacz postęp kontrolera w iOS8” prelegent również przedstawia rozwiązanie tego problemu, stosując metodę, która zastępuje -will/DidRotateToInterfaceOrientation.

Tutaj proponowane rozwiązanie częściowo wdrożone, więcej informacji tutaj :

func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        let orientation = orientationFromTransform(coordinator.targetTransform())
        let oldOrientation = UIApplication.sharedApplication().statusBarOrientation
        myWillRotateToInterfaceOrientation(orientation,duration: duration)
        coordinator.animateAlongsideTransition({ (ctx) in
            self.myWillAnimateRotationToInterfaceOrientation(orientation,
            duration:duration)
            }) { (ctx) in
                self.myDidAnimateFromInterfaceOrientation(oldOrientation)
        }
    }
Andrea
źródło
11

Wiem, że to pytanie jest dla Swift, ale ponieważ jest to jeden z najlepszych linków do wyszukiwania Google i jeśli szukasz tego samego kodu w Objective-C:

// add the observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotated:) name:UIDeviceOrientationDidChangeNotification object:nil];

// remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

// method signature
- (void)rotated:(NSNotification *)notification {
    // do stuff here
}
mikeho
źródło
11

Spokojnie, działa to w iOS8 i 9 / Swift 2 / Xcode7, po prostu umieść ten kod w swoim viewcontroller.swift. Wydrukuje wymiary ekranu przy każdej zmianie orientacji, możesz zamiast tego umieścić własny kod:

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
        getScreenSize()
    }
    var screenWidth:CGFloat=0
    var screenHeight:CGFloat=0
    func getScreenSize(){
        screenWidth=UIScreen.mainScreen().bounds.width
        screenHeight=UIScreen.mainScreen().bounds.height
        print("SCREEN RESOLUTION: "+screenWidth.description+" x "+screenHeight.description)
    }
Josh
źródło
5
Ta funkcja została wycofana. Zamiast tego użyj „viewWillTransitionToSize: withTransitionCoordinator:”
Masa S-AiYa
Oprócz tego, didRotateFromInterfaceOrientation()że jest przestarzały, nie działa niezawodnie. Brakuje niektórych obrotów. iewWillTransitionToSize:withTransitionCoordinator:działa dobrze.
Andrej
@Andrej Wiele rzeczy jest teraz przestarzałych dzięki Swift 3
Josh
9

Lubię sprawdzać powiadomienie o orientacji, ponieważ możesz dodać tę funkcję w dowolnej klasie, nie musi być widokiem ani kontrolerem widoku. Nawet w delegacie aplikacji.

SWIFT 5:

    //ask the system to start notifying when interface change
    UIDevice.current.beginGeneratingDeviceOrientationNotifications()
    //add the observer
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(orientationChanged(notification:)),
        name: UIDevice.orientationDidChangeNotification,
        object: nil)

niż buforowanie powiadomienia

    @objc func orientationChanged(notification : NSNotification) {
        //your code there
    }
Alberto Scampini
źródło
8

W celu C

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

Szybko

func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Zastąp tę metodę, aby wykryć zmianę orientacji.

Mahendra
źródło
8

Swift 3 | UIDeviceOrientationDidChange Powiadomienie obserwowane zbyt często

Poniższy kod drukuje „deviceDidRotate” za każdym razem, gdy urządzenie zmieni orientację w przestrzeni 3D - niezależnie od zmiany orientacji z pionowej na poziomą. Na przykład, jeśli trzymasz telefon w orientacji pionowej i przechylasz go do przodu i do tyłu - urządzenie deviceDidRotate () jest wywoływane wielokrotnie.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIDeviceOrientationDidChange, 
        object: nil
    )
}

func deviceDidRotate() {
    print("deviceDidRotate")
}

Aby obejść ten problem, możesz przytrzymać poprzednią orientację urządzenia i sprawdzić, czy nastąpiła zmiana w deviceDidRotate ().

var previousDeviceOrientation: UIDeviceOrientation = UIDevice.current.orientation

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIDeviceOrientationDidChange, 
        object: nil
    )
}

func deviceDidRotate() {
    if UIDevice.current.orientation == previousDeviceOrientation { return }
    previousDeviceOrientation = UIDevice.current.orientation
    print("deviceDidRotate")
}

Możesz też użyć innego powiadomienia, które jest wywoływane tylko wtedy, gdy urządzenie zmieni się z poziomego na pionowe. W takim przypadku chcesz skorzystać z UIApplicationDidChangeStatusBarOrientationpowiadomienia.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIApplicationDidChangeStatusBarOrientation, 
        object: nil
    )
}

func deviceDidRotate() {
    print("deviceDidRotate")
}
Derek Soike
źródło
6

Pełna funkcjonalna implementacja sposobu wykrywania zmiany orientacji w Swift 3.0.

Zdecydowałem się skorzystać z tej implementacji, ponieważ orientacje telefonu face upi face downbyły dla mnie ważne, a chciałem, aby widok zmieniał się tylko wtedy, gdy wiedziałem, że orientacja jest w określonej pozycji.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //1
        NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

    }

    deinit {
        //3
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
    }

    func deviceOrientationDidChange() {
        //2
        switch UIDevice.current.orientation {
        case .faceDown:
            print("Face down")
        case .faceUp:
            print("Face up")
        case .unknown:
            print("Unknown")
        case .landscapeLeft:
            print("Landscape left")
        case .landscapeRight:
            print("Landscape right")
        case .portrait:
            print("Portrait")
        case .portraitUpsideDown:
            print("Portrait upside down")
        }
    }

}

Ważne elementy, na które należy zwrócić uwagę, to:

  1. Odsłuchujesz strumień powiadomień DeviceOrientationDidChange i powiążesz go z funkcją deviceOrientationDidChange
  2. Następnie włączasz orientację urządzenia, pamiętaj, aby zauważyć, że unknownczasami jest orientacja.
  3. Podobnie jak w przypadku każdego powiadomienia, przed dezinicjalizacją elementu viewController należy zatrzymać obserwowanie strumienia powiadomień.

Mam nadzieję, że ktoś uzna to za pomocne.

Rob Norback
źródło
Dziękuję, świetnie
Mohammad Razipour
Więc jestem zdezorientowany, obecnie wszystkie moje widoki dostosowują się w zależności od portretu do krajobrazu, ale to się nie zmienia, jeśli urządzenie jest odkryte? Jak mógłbym użyć powyższego kodu, aby osiągnąć ten sam efekt, gdy jest on odkryty !?
Famic Tech
Czy możesz podać trochę więcej kontekstu? Nie jestem pewien, do jakiego efektu masz na myśli. Ten kod działa, aby po prostu wykryć orientację. Jeśli używasz wielu metod wykrywania orientacji, możesz napotkać problemy.
Rob Norback
6
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
    //swift 3
    getScreenSize()
}


func getScreenSize(){
   let screenWidth = UIScreen.main.bounds.width
   let  screenHeight = UIScreen.main.bounds.height
    print("SCREEN RESOLUTION: \(screenWidth.description) x \(screenHeight.description)")
}
Jeet Gandhi
źródło
Najczystsza odpowiedź. Pracował dla mnie.
Dorad
To jest teraz przestarzałe
Aziz Javed
5

Jeśli chcesz coś zrobić PO zakończeniu rotacji, możesz użyć UIViewControllerTransitionCoordinatorprocedury obsługi zakończenia w ten sposób

public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    // Hook in to the rotation animation completion handler
    coordinator.animate(alongsideTransition: nil) { (_) in
        // Updates to your UI...
        self.tableView.reloadData()
    }
}
David Pettigrew
źródło
5

Od iOS 8 jest to właściwy sposób na zrobienie tego.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    coordinator.animate(alongsideTransition: { context in
        // This is called during the animation
    }, completion: { context in
        // This is called after the rotation is finished. Equal to deprecated `didRotate`
    })
}
PatrickDotStar
źródło
4

Sprawdź, czy rotacja zmieniła się z: viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Z coordinator.animateAlongsideTransition(nil) { (UIViewControllerTransitionCoordinatorContext)można sprawdzić, czy przejście jest zakończona.

Zobacz kod poniżej:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition(nil) { (UIViewControllerTransitionCoordinatorContext) in
        // if you want to execute code after transition finished
        print("Transition finished")
    }

    if size.height < size.width {
        // Landscape
        print("Landscape")
    } else {
        // Portrait
        print("Portrait")
    }

}
SDW
źródło
4

Oto prosty sposób na wykrycie orientacji urządzenia: ( Swift 3 )

override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
            handleViewRotaion(orientation: toInterfaceOrientation)
        }

    //MARK: - Rotation controls
    func handleViewRotaion(orientation:UIInterfaceOrientation) -> Void {
        switch orientation {
        case .portrait :
            print("portrait view")
            break
        case .portraitUpsideDown :
            print("portraitUpsideDown view")
            break
        case .landscapeLeft :
            print("landscapeLeft view")
            break
        case .landscapeRight :
            print("landscapeRight view")
            break
        case .unknown :
            break
        }
    }
Ram Madhavan
źródło
2
willRotatejest teraz przestarzały, lepiej go używać viewWillTransition.
przed
4

Swift 4:

override func viewWillAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(deviceRotated), name: UIDevice.orientationDidChangeNotification, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
}

@objc func deviceRotated(){
    if UIDevice.current.orientation.isLandscape {
        //Code here
    } else {
        //Code here
    }
}

Wiele odpowiedzi nie pomaga, gdy trzeba wykryć różne kontrolery widoku. Ten załatwia sprawę.

Joel
źródło
Należy również sprawdzić, czy urządzenie zostało obrócone, podczas gdy kontroler widoku zniknął (w przypadku, gdy inny kontroler widoku jest otwarty powyżej prądu). W rzeczywistości, można pominąć viewWillDisappeari dodać addObserverw viewDidLoad. iOS automatycznie anuluje subskrypcję kontrolera widoku.
Alexander Volkov
zapomniałeśUIDevice.current.orientation.isFlat
user924
3

Moje podejście jest podobne do tego, co pokazuje bpedit powyżej, ale koncentruje się na iOS 9+. Chciałem zmienić zakres FSCalendar, gdy widok się obraca.

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition({ (context) in
        if size.height < size.width {
            self.calendar.setScope(.Week, animated: true)
            self.calendar.appearance.cellShape = .Rectangle
        }
        else {
            self.calendar.appearance.cellShape = .Circle
            self.calendar.setScope(.Month, animated: true)

        }

        }, completion: nil)
}

To poniżej działało, ale czułem się z tego powodu zakłopotany :)

coordinator.animateAlongsideTransition({ (context) in
        if size.height < size.width {
            self.calendar.scope = .Week
            self.calendar.appearance.cellShape = .Rectangle
        }
        }) { (context) in
            if size.height > size.width {
                self.calendar.scope = .Month
                self.calendar.appearance.cellShape = .Circle
            }
    }
Curtis Forrester
źródło
2

Używam UIUserInterfaceSizeClassdo wykrywania zmiany orientacji w UIViewControllerklasie, po prostu:

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {

    let isiPadLandscapePortrait = newCollection.horizontalSizeClass == .regular && newCollection.verticalSizeClass == .regular
    let isiPhonePlustLandscape = newCollection.horizontalSizeClass == .regular && newCollection.verticalSizeClass == .compact
    let isiPhonePortrait = newCollection.horizontalSizeClass == .compact && newCollection.verticalSizeClass == .regular
    let isiPhoneLandscape = newCollection.horizontalSizeClass == .compact && newCollection.verticalSizeClass == .compact

     if isiPhonePortrait {
         // do something...
     }
}
pableiros
źródło
1

Dla Swift 3

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        //Landscape
    }
    else if UIDevice.current.orientation.isFlat {
        //isFlat
    }
    else {
        //Portrait
    }
}
Mamta
źródło
zapomniałeśUIDevice.current.orientation.isFlat
user924
1

Szybki 5

Skonfiguruj klasę, aby otrzymywać powiadomienia o zmianie orientacji urządzenia:

class MyClass {

    ...

    init (...) {

        ...

        super.init(...)

        // subscribe to device orientation change notifications
        UIDevice.current.beginGeneratingDeviceOrientationNotifications()
        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)

        ...

    }

    ...

}

Kod obsługi konfiguracji:

@objc extension MyClass {
    func orientationChanged(_ notification: NSNotification) {
        let device = notification.object as! UIDevice
        let deviceOrientation = device.orientation

        switch deviceOrientation {
        case .landscapeLeft:   //do something for landscape left
        case .landscapeRight:  //do something for landscape right
        case .portrait:        //do something for portrait
        case .portraitUpsideDown: //do something for portrait upside-down 
        case .faceDown:        //do something for face down
        case .faceUp:          //do something for face up
        case .unknown:         //handle unknown
        @unknown default:      //handle unknown default
        }
    }
}
Jacob Barnard
źródło
0
- (void)viewDidLoad {
  [super viewDidLoad];
  [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(OrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

-(void)OrientationDidChange:(NSNotification*)notification {
  UIDeviceOrientation Orientation=[[UIDevice currentDevice]orientation];

  if(Orientation==UIDeviceOrientationLandscapeLeft || Orientation==UIDeviceOrientationLandscapeRight) {
    NSLog(@"Landscape");
  } else if(Orientation==UIDeviceOrientationPortrait) {
    NSLog(@"Potrait Mode");
  }
}

UWAGA: Po prostu użyj tego kodu, aby zidentyfikować UIViewController, w której orientacji

Mannam Brahmam
źródło
Twój kod nie działa w projekcie. czy muszę też zrobić coś innego?
Syed Ali Salman
0
override func viewDidLoad() {
    NotificationCenter.default.addObserver(self, selector: #selector(MyController.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
//...
}

@objc
private func rotated() {
    if UIDevice.current.orientation.isLandscape {

    } else if UIDevice.current.orientation.isPortrait {

    }

    //or you can check orientation separately UIDevice.current.orientation
    //portrait, portraitUpsideDown, landscapeLeft, landscapeRight... 

}
yoAlex5
źródło
0

W iOS 13.1.2 orientacja zawsze zwraca 0 do momentu obrócenia urządzenia. Muszę zadzwonić do UIDevice.current.beginGeneratingDeviceOrientationNotifications (), aby uzyskać rzeczywistą rotację przed wystąpieniem jakiegokolwiek zdarzenia rotacji.

Ozgur Sahin
źródło