获取设备当前方向(应用程序扩展)

如何在应用程序扩展中获取设备当前的方向,我尝试了下面两种方法,但没有成功。

  1. 它总是返回UIDeviceOrientationUnknown

    [[UIDevice currentDevice] orientation] 
  2. 它显示红色消息,“共享应用程序”不适用于iOS(应用程序扩展)

     [[UIApplication sharedApplication] statusBarOrientation]; 
  3. 我也添加了一个观察者,但没有被调用。

     [[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"]; } 

那么现在怎样才能获得当前的设备定位。

我发现了一种方法,可以像这样在(应用程序扩展)中计算我们的设备方向

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

它给了我正确的方向,但仍然没有得到作为设备是LandscapeLeftLandscapeRight以及肖像PortraitUppsideDown

仍然需要帮助。

我有一个主意!

 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 } } } 

编辑:在斯威夫特4你可以做:

 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 } } } 

观察者方法将被调用,如果你添加之前: [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

编辑:我使用UIApplicationDidChangeStatusBarOrientationNotification的观察员

在我的方法中,我检查:

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

编辑2- Xcode 6.2 – iOS 7和8

看来,如果你想在iOS 7和8上使用这个,上面的代码会给你在iOS 7上的错误结果。

所以我使用其他的东西,因为在iOS 7上,mainScreen的边界永远不会改变,但是如果方向改变的话,iOS 8将会改变。

我有3个macros,无论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) 

然后,当通知被触发,我检查方向是这样的:

 BOOL isPortrait = SCREEN_WIDTH_CALCULATED < SCREEN_HEIGHT_CALCULATED; 

这将在iOS 7和iOS 8上工作,但我没有检查旧版本的Xcode,只有6.2

只有当设备处于纵向或横向时,才会返回,而不是全部4种方向types

你可以看看这个图书馆和它的叉子 。 它使用CoreMotion来检测设备的方向,因此它可以在App Extension的受限制的环境中工作。

我知道已经很晚了,但是这个问题的错误在于这一行:

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

addObserver:self.view是错误的,通知应该被附加在self被调用。 也在iOS8上工作。

这段代码不会给你确切的UIDeviceOrientation,但你将能够知道它是在纵向还是横向模式

 BOOL isLandScape = !(self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height)));