App Extensionでデバイスの現在の向きを取得する方法として、以下の2つの方法を試しましたが、成功しませんでした。
常にUIDeviceOrientationUnknownを返します
[[UIDevice currentDevice] orientation]
「sharedApplication」はiOS(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"];
}
では、どのようにすれば誰でも現在のデバイスの向きを知ることができます。
アイデアが浮かんだ!
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
}
}
}
(App Extension)でこのようにデバイスの向きを計算できる方法を見つけました
- (void)viewDidLayoutSubviews
{
if(self.view.frame.size.width > self.view.frame.size.height)
NSLog(@"Landscape");
else
NSLog(@"Portrait");
}
デバイスはLandscapeLeftまたはLandscapeRightおよびPortraitまたはPortraitUpsideDownであるため、正しい方向が得られますが、まだ取得できません。
まだ助けが必要です。
前にこれを追加すると、オブザーバーメソッドが呼び出されます:_[[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では方向が変わると変更されます。
IOSのバージョンに関係なく、画面の幅と高さの適切なサイズを提供する3つのマクロがあります。
_#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種類のすべての向きではありません
BroadcastExtensionでは、sampleBufferを使用して方向を理解できます。
if let orientationAttachment = CMGetAttachment(sampleBuffer, RPVideoSampleOrientationKey as CFString, nil) as? NSNumber
{
let orientation = CGImagePropertyOrientation(rawValue: orientationAttachment.uint32Value)
}
私はそれが遅いことを知っていますが、この質問の間違いはこの行にありました:
[[NSNotificationCenter defaultCenter] addObserver:self.view selector:@selector(notification_OrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
addObserver:self.view
が間違っています。通知はself
に添付して呼び出す必要があります。 iOS8でも動作します。
IMessage App Extensionで機能させることができませんでした。 Apple私が知る限り、黙ってそれを無効にしているようです https://forums.developer.Apple.com/thread/53981
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")
}
}