如何在App Extension中获取设备当前方向,我尝试了以下两种方法,但没有成功。
它始终返回UIDeviceOrientationUnknown
[[UIDevice currentDevice] orientation]
它显示红色消息“iOS上没有'sharedApplication'(App Extension)
[[UIApplication sharedApplication] statusBarOrientation];
我还添加了一个观察者,但没有被调用。
[[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"];
}
现在,任何人都可以获得当前的设备定位。
答案 0 :(得分:11)
我有个主意!
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
}
}
}
编辑:在Swift 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
}
}
}
答案 1 :(得分:9)
我找到了一种方法,可以在(应用扩展程序)
中以这种方式计算我们的设备方向- (void)viewDidLayoutSubviews
{
if(self.view.frame.size.width > self.view.frame.size.height)
NSLog(@"Landscape");
else
NSLog(@"Portrait");
}
它给了我正确的方向,但仍然没有得到设备 LandscapeLeft 或 LandscapeRight 以及 Portrait 或 PortraitUpsideDown 。
仍然需要帮助。
答案 2 :(得分:6)
如果您之前添加了此方法,则会调用observer方法:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
编辑:我使用UIApplicationDidChangeStatusBarOrientationNotification
作为观察者
在我的方法中,我检查:
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
BOOL isPortrait = UIDeviceOrientationIsPortrait(orientation);
编辑2- Xcode 6.2 - iOS 7& 8 强>
似乎如果你想在iOS 7和iOS上使用它8,上面的代码会在iOS 7上给出错误的结果。
所以我使用别的东西,因为在iOS 7上,主屏幕的界限永远不会改变,但是如果方向改变,iOS 8将会改变。
我有3个宏,它们会给我正确的屏幕尺寸和宽度&高度,无论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&amp; iOS 8,但我没有检查旧版本的Xcode,只有6.2
仅当设备处于纵向或横向时才会返回,而不是所有4种方向类型
答案 3 :(得分:0)
答案 4 :(得分:0)
我知道它已经很晚了,但这个问题的错误在于这一行:
[[NSNotificationCenter defaultCenter] addObserver:self.view selector:@selector(notification_OrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
addObserver:self.view
错误,通知应附在self
上以便被调用。也适用于iOS8。
答案 5 :(得分:0)
使用CoreMotion框架可以获得设备方向。
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")
}
}
答案 6 :(得分:0)
在BroadcastExtension中,您可以使用sampleBuffer来了解方向:
if let orientationAttachment = CMGetAttachment(sampleBuffer, RPVideoSampleOrientationKey as CFString, nil) as? NSNumber
{
let orientation = CGImagePropertyOrientation(rawValue: orientationAttachment.uint32Value)
}
答案 7 :(得分:0)
我无法使其在iMessage App Extension中工作。据我所知,苹果似乎默默地禁用了它。 https://forums.developer.apple.com/thread/53981
答案 8 :(得分:-1)
此代码不会为您提供准确的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)));
答案 9 :(得分:-1)
我已经完成了自定义键盘扩展名,希望对您有帮助。
为了在方向更改时更新自定义键盘,请覆盖UIInputViewController中的viewDidLayoutSubviews。换句话说,可以说在旋转完成后总是调用viewDidLayoutSubviews。
在键盘扩展中,我们无法像往常一样使用传统流程:
[UIApplication sharedApplication] statusBarOrientation]
因此,要检测当前方向,我使用了以下代码: 在Objc中:
if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
// Portrait Orientation
}
else{
//Landscape Orientation
}
在swift4中,您可以使用以下代码:
if UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height {
//portrait Orientation
}
else
{
//landscape Orientation
}