web-dev-qa-db-fra.com

Obtenir l'orientation actuelle du périphérique (App Extension)

Comment obtenir l'orientation actuelle du périphérique dans une extension d'application, j'ai essayé ci-dessous deux méthodes, mais sans succès.

  1. Il retourne toujours UIDeviceOrientationUnknown

    [[UIDevice currentDevice] orientation]
    
  2. Il affiche un message rouge indiquant que «sharedApplication» n'est pas disponible sur iOS (App Extension).

    [[UIApplication sharedApplication] statusBarOrientation];
    
  3. J'ajoute aussi un observateur mais il ne s'appelle pas.

    [[NSNotificationCenter defaultCenter] addObserver:self.view selector:@selector(notification_OrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
    
    
    
    - (void)notification_OrientationWillChange:(NSNotification*)n
    {
       UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[n.userInfo objectForKey:UIApplicationStatusBarOrientationUserInfoKey] intValue];
    
        if (orientation == UIInterfaceOrientationLandscapeLeft)
           [self.textDocumentProxy insertText:@"Left"];
        if (orientation == UIInterfaceOrientationLandscapeRight)
           [self.textDocumentProxy insertText:@"Right"];
    }
    

Alors maintenant, comment peut-on avoir une orientation de périphérique actuelle.

16
Anand Suthar

J'ai une idée!

extension UIScreen {

    var orientation: UIInterfaceOrientation {
        let point = coordinateSpace.convertPoint(CGPointZero, toCoordinateSpace: fixedCoordinateSpace)
        if point == CGPointZero {
            return .Portrait
        } else if point.x != 0 && point.y != 0 {
            return .PortraitUpsideDown
        } else if point.x == 0 && point.y != 0 {
            return .LandscapeLeft
        } else if point.x != 0 && point.y == 0 {
            return .LandscapeRight
        } else {
            return .Unknown
        }
    }

}

EDIT: Sur Swift 4, vous pouvez faire:

extension UIScreen {
    var orientation: UIInterfaceOrientation {
        let point = coordinateSpace.convert(CGPoint.zero, to: fixedCoordinateSpace)
        switch (point.x, point.y) {
        case (0, 0):
            return .portrait
        case let (x, y) where x != 0 && y != 0:
            return .portraitUpsideDown
        case let (0, y) where y != 0:
            return .landscapeLeft
        case let (x, 0) where x != 0:
            return .landscapeRight
        default:
            return .unknown
        }
    }
}
11
mmtootmm

J'ai trouvé un moyen de calculer l'orientation de notre appareil de cette manière dans (App Extension)

- (void)viewDidLayoutSubviews
{
   if(self.view.frame.size.width > self.view.frame.size.height)
      NSLog(@"Landscape");
   else
      NSLog(@"Portrait");
}

Cela me donne la bonne orientation mais ne fonctionne toujours pas car le périphérique est LandscapeLeft ou LandscapeRight ainsi que Portrait ou PortraitUpsideDown

Encore besoin d'aide.

9
Anand Suthar

La méthode observateur sera appelée si vous ajoutez ceci avant: [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

Edit: J'utilise UIApplicationDidChangeStatusBarOrientationNotification pour l'observateur

Et dans ma méthode je vérifie:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; BOOL isPortrait = UIDeviceOrientationIsPortrait(orientation);

Édition 2- Xcode 6.2 - iOS 7 & 8

Il semble que si vous voulez utiliser cela sur iOS 7 & 8, le code ci-dessus vous donnera un résultat erroné sur iOS 7.

J'utilise donc autre chose car sur iOS 7, les limites de l'écran principal ne changeront jamais, mais sur iOS 8, elles changeront si l'orientation change. 

J'ai 3 macros qui me donneront la bonne taille de la largeur et de la hauteur de l'écran quelle que soit la version iOS:

#define IOS_VERSION_OLDER_THAN_8 ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)

#define SCREEN_WIDTH_CALCULATED (IOS_VERSION_OLDER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)

#define SCREEN_HEIGHT_CALCULATED (IOS_VERSION_OLDER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)

Puis, lorsque la notification est déclenchée, je vérifie l'orientation comme suit:

BOOL isPortrait = SCREEN_WIDTH_CALCULATED < SCREEN_HEIGHT_CALCULATED;

Cela fonctionnera sur iOS 7 et iOS 8, mais je n'ai pas vérifié d'anciennes versions de Xcode, seulement 6.2

Ceci ne sera renvoyé que si l'appareil est en mode portrait ou paysage, mais pas avec les 4 types d'orientation

6
Aura

Je sais qu'il est tard, mais l'erreur dans cette question était dans cette ligne: 

[[NSNotificationCenter defaultCenter] addObserver:self.view selector:@selector(notification_OrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];

addObserver:self.view est incorrect, la notification doit être jointe à self pour être appelée. Fonctionne aussi sur iOS8. 

0
Benetz

Je n'ai pas réussi à le faire fonctionner dans une extension d'application iMessage. Apple semble l'avoir désactivé en silence, autant que je sache. https://forums.developer.Apple.com/thread/53981

0
Gandalf458

L'utilisation de la structure CoreMotion permet d'obtenir l'orientation du périphérique.

func startMonitorDeviceOrientation() {
    if motionManager.isDeviceMotionAvailable {
        motionManager.deviceMotionUpdateInterval = 1.0
        let queue = OperationQueue()

        motionManager.startDeviceMotionUpdates(to: queue) { (deviceMotion, error) in
            guard let x = deviceMotion?.gravity.x,
            let y = deviceMotion?.gravity.y
            else {
                return
            }

            if fabs(y) >= fabs(x) {
                if y >= 0 {
                    // UIDeviceOrientationPortraitUpsideDown;
                    print("device orientation UIDeviceOrientationPortraitUpsideDown")
                } else {
                    // UIDeviceOrientationPortrait;
                    print("device orientation UIDeviceOrientationPortrait")
                }
            } else {
                if x >= 0 {
                    // UIDeviceOrientationLandscapeRight;
                    print("device orientation UIDeviceOrientationLandscapeRight")
                } else {
                    // UIDeviceOrientationLandscapeLeft;
                    print("device orientation UIDeviceOrientationLandscapeLeft")
                }
            }
        }
    } else {
        print("Device motion is not avaliable")
    }
}
0
Passaction

Dans BroadcastExtension, vous pouvez utiliser sampleBuffer pour comprendre l'orientation:

if let orientationAttachment =  CMGetAttachment(sampleBuffer, RPVideoSampleOrientationKey as CFString, nil) as? NSNumber 
{  
          let orientation = CGImagePropertyOrientation(rawValue: orientationAttachment.uint32Value)   
}
0
Bws Sluk

Vous pouvez regarder this library et ses fourchettes . Il utilise CoreMotion pour détecter l'orientation du périphérique afin qu'il puisse fonctionner sur l'environnement restreint d'App Extension.

0
Rivera