Erkennen der Ausrichtung von iOS UIDevice

71

Ich muss erkennen, wann sich das Gerät im Hochformat befindet, damit ich eine spezielle Animation auslösen kann. Ich möchte jedoch nicht, dass sich meine Ansicht automatisch dreht.

Wie überschreibe ich eine Ansicht, die automatisch gedreht wird, wenn das Gerät auf Hochformat gedreht wird? Meine App muss nur die Ansicht im Querformat anzeigen, aber anscheinend muss ich auch das Hochformat unterstützen, wenn ich eine Drehung zum Hochformat erkennen möchte.

Jace999
quelle
Hinweis. Es ist wahrscheinlich moderner, nur zu verwenden viewDidLayoutSubviews, um alle Layoutänderungen zu berücksichtigen. (Denken Sie daran, dass Benutzer in naher Zukunft die Größe von Apps in Windows auf Geräten ändern werden.) Reaktives Layout ist derzeit die Norm.
Fattie

Antworten:

173

Führen Sie die folgenden Schritte aus, wenn die Anwendung geladen wird oder wenn Ihre Ansicht geladen wird:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
   addObserver:self selector:@selector(orientationChanged:)
   name:UIDeviceOrientationDidChangeNotification
   object:[UIDevice currentDevice]];

Fügen Sie dann die folgende Methode hinzu:

- (void) orientationChanged:(NSNotification *)note
{
   UIDevice * device = note.object;
   switch(device.orientation)
   {
       case UIDeviceOrientationPortrait:
       /* start special animation */
       break;

       case UIDeviceOrientationPortraitUpsideDown:
       /* start special animation */
       break;

       default:
       break;
   };
}

Mit den oben genannten Informationen können Sie sich für Orientierungsänderungen des Geräts registrieren, ohne die automatische Rotation Ihrer Ansicht zu aktivieren.


Hinweis

Wenn Sie in iOS einen Beobachter hinzufügen, entfernen Sie ihn in allen Fällen auch zu geeigneten Zeiten (möglicherweise, aber nicht immer, wenn die Ansicht angezeigt / ausgeblendet wird). Sie können nur "Paare" von Beobachtungs- / Nichtbeobachtungscode haben. Wenn Sie dies nicht tun, stürzt die App ab. Die Auswahl, wo beobachtet / nicht beobachtet werden soll, liegt außerhalb des Rahmens dieser Qualitätssicherung. Sie müssen jedoch ein "Unobserve" haben, um mit dem obigen "Observ" -Code übereinzustimmen.

David M. Syzdek
quelle
Hier gibt es etwas, auf das Sie achten müssen. (int) device.orientation kann 1 oder 2 im Hochformat, 3 oder 4 im Querformat sein. Und es gibt eine "5", was bedeutet, dass das Gerät einfach auf einem Schreibtisch steht, der als Querformat zurückgegeben wird, wenn Sie mit UIDeviceOrientationIsLandscape (device.orientation) prüfen. Sie können diese "Querformat" -Antwort erhalten, obwohl sich Ihre App / Ihr Gerät im Hochformat befindet.
Emrahgunduz
1
UIDevice gibt keine Orientierung, wenn die App gestartet wird und bis die App die Orientierung ändert. Andere Möglichkeit für iOS> 5 [UIApplication sharedApplication] .statusBarOrientation
khunshan
Vergessen Sie nicht, den Beobachter an einer geeigneten Stelle zu entfernen (je nachdem, wo Sie ihn hinzugefügt haben), da Sie sonst eine Ausnahme erhalten.
Amr Lotfy
21

Wenn Sie zu dieser Frage gekommen sind, um herauszufinden, wie Sie eine Orientierungsänderung erkennen können (ohne die Drehung unbedingt deaktivieren zu wollen), sollten Sie sich auch darüber im Klaren sein viewWillTransitionToSize, was unter iOS 8 verfügbar ist.

Schnelles Beispiel von hier

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

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            println("Portrait")
            // Do something
        default:
            println("Anything But Portrait")
            // Do something else
        }

        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            println("rotation completed")
    })

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Und wenn Sie sich keine Gedanken über die tatsächliche Ausrichtung machen müssen:

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

    // do something

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Objective-C-Beispiel von hier

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{   
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
        // do whatever
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    { 

    }];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Und wenn Sie sich keine Gedanken über die tatsächliche Ausrichtung machen müssen (aus dieser Antwort entnommen ):

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Do view manipulation here.
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Siehe auch

Suragch
quelle
viewWillTransitionToSize ruft auch dann auf, wenn Sie das Drücken der App oder des Netzschalters minimieren.
Rajneesh071
3

1) Schnelle Version von Davids Antwort 2) Falls Sie die Ausrichtung immer noch erkennen möchten, wenn sich die Ausrichtung nicht ändert (Schnelle Version von Moes Antwort auf Wie erkenne ich die Ausrichtung des Geräts unter iOS? )

    // Initial device orientation
    let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
    if(orientation == UIInterfaceOrientation.Unknown){
        // code for Unknown
    }
    else if(orientation == UIInterfaceOrientation.Portrait){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.LandscapeRight){
        // code for Landscape        
    }
    else if(orientation == UIInterfaceOrientation.LandscapeLeft){
        // ode for Landscape
    }

    // To detect device orientation change
    UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "orientationChanged:",
        name: UIDeviceOrientationDidChangeNotification,
        object: UIDevice.currentDevice())

Orientierungsänderung

func orientationChanged(note: NSNotification)
{
    let device: UIDevice = note.object as! UIDevice
    switch(device.orientation)
    {
        case UIDeviceOrientation.Portrait:
        // code for Portrait
        break
        case UIDeviceOrientation.PortraitUpsideDown:
        // code for Portrait
        break
        case UIDeviceOrientation.LandscapeLeft:
        // code for Landscape
        break
        case UIDeviceOrientation.LandscapeRight:
        // code for Landscape
        break
        case UIDeviceOrientation.Unknown:
        // code for Unknown
        break
        default:
        break
    }
}
Tsuneyuki Ohsaki
quelle
1

Wenn ich Sie richtig verstehe, ist Ihre App nur im Querformat. Sie können im Apps-Setup einfach angeben, dass es sich nur um Querformat handelt und Sie sich daher keine Gedanken über die Rotation machen müssen. Die App startet im Querformat und bleibt dort, unabhängig davon, wie das iPad ausgerichtet ist.

drekka
quelle
Lassen Sie es mich anhand eines einfachen Beispiels erklären. Ich habe eine App, die im Querformat angezeigt werden soll. Meine Ansicht zeigt einen Tisch mit einem Ball oben. Wenn das Gerät zum Hochdrehen gedreht wird, rollt der Ball vom Tisch. Alles bleibt Landschaft, der Tisch, der Hintergrund usw.
Jace999
1

Wenn Sie kein Geräteobjekt erstellen möchten, können Sie auch verwenden

-(void) seObserverForOrientationChanging
{
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(orientationChanged:)
     name:UIDeviceOrientationDidChangeNotification
     object:[UIDevice currentDevice]];
}


- (void) orientationChanged:(NSNotification *)note
{
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
        //Do something in landscape
    }
    else {
        //Do something in portrait
    }
}
B. Kosmowski
quelle
0

Deaktivieren Sie zuerst alle außer der gewünschten Ausrichtung (damit sie sich nicht dreht).

Dann, wie David sagte, erhalten Sie einfach die aktuelle Ausrichtung des Geräts:

https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html

Alternativ können Sie den Beschleunigungsmesser einfach selbst verwenden (da dies sowieso so ist) und überprüfen, wo sich die Schwerkraft befindet, um festzustellen, welche Ausrichtung er hat. Wenn Sie diesen Ansatz wählen, können Sie selbst mit den Werten spielen, um unterschiedliche Ergebnisse zu erzielen.

Pochi
quelle
0

.UIDeviceOrientationDidChangeDie Benachrichtigung wird auf dem iPhone viele Male aufgerufen, auch wenn sich das Gerät nicht gedreht hat. Sie kennen den Grund nicht, aber wenn Sie ihn nur benötigen, wenn sich das Gerät wirklich gedreht hat, gehen Sie wie folgt vor.

NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)

Die vom Beobachter aufgerufene Methode sollte folgendermaßen aussehen:

func orientationChanged() {

    if traitCollection.isIphone {

        defer {
            self.previousTraitCollectionForIphone = traitCollection
        }

        guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {

            updateView()
            return
        }

        if previousTraitCollectionForIphone != traitCollection {
            updateView()
        }

    } else {
        updateView()
    }
}
Bartłomiej Semańczyk
quelle
Schöne Lösung. Eines: traitCollection.isIphone wird in Xcode 8.3 - Swift 3.1 nicht erkannt. Verwenden Sie traitCollection.userInterfaceIdiom == .phone
guido
0

In Swift 5.0.

DeviceOrientation vs. ScreenSize vs StatusBar.isLandscape?

Wenn Sie Orientierungsänderungen im Hintergrund erkennen möchten und auch Änderungen von oben nach unten erkennen müssen, überprüfen Sie diesen Link . Wie können Sie in Swift die Ausrichtung des Geräts direkt nach dem Start korrekt ermitteln?

Es wird erläutert, wie die Ausrichtung in Swift auf drei verschiedene Arten korrekt erkannt wird: - viewWillTransitionToSize () - Verwenden von Observer - Verwenden der Statusleiste

eharo2
quelle