我有一个关于如何在iOS上检测设备方向的问题。我不需要接收更改通知,只需要接收当前方向。这似乎是一个相当简单的问题,但我无法绕过它。以下是我到目前为止所做的事情:
UIDevice *myDevice = [UIDevice currentDevice] ;
[myDevice beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation deviceOrientation = myDevice.orientation;
BOOL isCurrentlyLandscapeView = UIDeviceOrientationIsLandscape(deviceOrientation);
[myDevice endGeneratingDeviceOrientationNotifications];
在我看来这应该有效。我启用设备接收设备方向通知,然后询问它的方向,但它不起作用,我不知道为什么。
答案 0 :(得分:118)
真的老线程,但没有真正的解决方案。
我有同样的问题,但发现获取UIDeviceOrientation并不总是一致的,所以改为使用:
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == 0) //Default orientation
//UI is in Default (Portrait) -- this is really a just a failsafe.
else if(orientation == UIInterfaceOrientationPortrait)
//Do something if the orientation is in Portrait
else if(orientation == UIInterfaceOrientationLandscapeLeft)
// Do something if Left
else if(orientation == UIInterfaceOrientationLandscapeRight)
//Do something if right
答案 1 :(得分:77)
如果是UIViewController:
if (UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
//
}
如果UIView:
if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
{
//
}
UIDevice.h:
#define UIDeviceOrientationIsPortrait(orientation) ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown)
#define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)
<强>更新强>:
将此代码添加到xxx-Prefix.pch,然后您可以在任何地方使用它:
// check device orientation
#define dDeviceOrientation [[UIDevice currentDevice] orientation]
#define isPortrait UIDeviceOrientationIsPortrait(dDeviceOrientation)
#define isLandscape UIDeviceOrientationIsLandscape(dDeviceOrientation)
#define isFaceUp dDeviceOrientation == UIDeviceOrientationFaceUp ? YES : NO
#define isFaceDown dDeviceOrientation == UIDeviceOrientationFaceDown ? YES : NO
用法:
if (isLandscape) { NSLog(@"Landscape"); }
答案 2 :(得分:22)
对于您首先要寻找的内容,如果方向发生变化,您必须获得通知! 您可以在viewDidLoad中设置This Thing,如
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(OrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
每当您的设备的方向发生变化时 OrientationDidChange 会调用您可以按照每个方向执行任何操作的位置
-(void)OrientationDidChange:(NSNotification*)notification
{
UIDeviceOrientation Orientation=[[UIDevice currentDevice]orientation];
if(Orientation==UIDeviceOrientationLandscapeLeft || Orientation==UIDeviceOrientationLandscapeRight)
{
}
else if(Orientation==UIDeviceOrientationPortrait)
{
}
}
答案 3 :(得分:22)
如果您想直接从加速度计获取设备方向,请使用[[UIDevice currentDevice] orientation]
。但是,如果您需要应用程序的当前方向(界面方向),请使用[[UIApplication sharedApplication] statusBarOrientation]
。
答案 4 :(得分:9)
UIViewController
有一个interfaceOrientation
属性,您可以访问该属性以查找视图控制器的当前方向。
至于你的例子,这应该有效。当你说它不起作用时,你的意思是什么?它会给你带来什么结果与你期望的结果?
答案 5 :(得分:7)
在Swift 3.0中
以获取设备方向。
/* return current device orientation.
This will return UIDeviceOrientationUnknown unless device orientation notifications are being generated.
*/
UIDevice.current.orientation
从您的应用中获取设备方向
UIApplication.shared.statusBarOrientation
答案 6 :(得分:4)
“UIDeviceOrientation”不满意,因为当UIViewcontroller方向固定到特定方向时,您无法获得有关设备方向的相关信息,因此正确的做法是使用的 “UIInterfaceOrientation”即可。
您可以使用“self.interfaceOrientation”从UIViewController获取方向,但是当您分解我们的代码时,您可能需要在视图控制器外进行此类测试,(自定义)查看,类别...),因此您仍然可以使用 rootviewController 访问控制器外的任何位置信息:
if (UIInterfaceOrientationIsLandscape(view.window.rootViewController.interfaceOrientation)) {
}
答案 7 :(得分:2)
通过使用CoreMotion中的数据,无论方向锁定是否启用,都可以实现此目的。 这是代码:
#import <CoreMotion/CoreMotion.h>
CMMotionManager *cm=[[CMMotionManager alloc] init];
cm.deviceMotionUpdateInterval=0.2f;
[cm startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMDeviceMotion *data, NSError *error) {
if(fabs(data.gravity.x)>fabs(data.gravity.y)){
NSLog(@"LANSCAPE");
if(data.gravity.x>=0){
NSLog(@"LEFT");
}
else{
NSLog(@"RIGHT");
}
}
else{
NSLog(@"PORTRAIT");
if(data.gravity.y>=0){
NSLog(@"DOWN");
}
else{
NSLog(@"UP");
}
}
}];
答案 8 :(得分:1)
您是否解锁了硬件锁以获取设备方向? iPad 1的边缘有一个。
答案 9 :(得分:1)
以下是一些使检测更容易的Swift变量:
CHANGELOG.md
答案 10 :(得分:0)
我目前的做法:
+ (BOOL)isPortrait {
let window = UIApplication.sharedApplication.delegate.window;
if(window.rootViewController) {
let orientation =
window.rootViewController.interfaceOrientation;
return UIInterfaceOrientationIsPortrait(orientation);
} else {
let orientation =
UIApplication.sharedApplication.statusBarOrientation;
return UIInterfaceOrientationIsPortrait(orientation);
}
}
如果由于某种原因,没有rootViewController仍然无法安全地进行statusBarOrientation ...
答案 11 :(得分:0)
最快捷的最佳可靠方式:
public extension UIScreen {
public class var isPortrait: Bool {
UIApplication.shared.delegate?.window??.rootViewController?.interfaceOrientation.isPortrait ??
UIApplication.shared.statusBarOrientation.isPortrait
}
public class var isLandscape: Bool { !isPortrait }
}
答案 12 :(得分:0)
这是我使用 Combine 的解决方案,它非常容易与 SwiftUI 或常规 Swift 对象一起使用。对于这种真正的全局对象,单例对象(静态实例)比“环境”更好。
// Singleton object to keep the interface orientation (and any other global state)
class SceneContext: ObservableObject {
@Published var interfaceOrientation = UIInterfaceOrientation.portrait
static let shared = SceneContext()
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
func windowScene(_ windowScene: UIWindowScene, didUpdate previousCoordinateSpace: UICoordinateSpace, interfaceOrientation previousInterfaceOrientation: UIInterfaceOrientation, traitCollection previousTraitCollection: UITraitCollection) {
SceneContext.shared.interfaceOrientation = windowScene.interfaceOrientation
}
}
// if you want to execute some code whenever the orientation changes in SwiftUI
someView {
....
}
.onReceive(SceneContext.shared.$interfaceOrientation) { (orientation) in
// do something with the new orientation
}
// if you want to execute some code whenever the orientation changes in a regular Swift object
let pub = SceneContext.shared.$interfaceOrientation.sink(receiveValue: { (orientation) in
// do something with the new orientation
...
})
答案 13 :(得分:0)
使用此功能。
func deviceOrientation() -> String! {
let device = UIDevice.current
if device.isGeneratingDeviceOrientationNotifications {
device.beginGeneratingDeviceOrientationNotifications()
var deviceOrientation: String
let deviceOrientationRaw = device.orientation.rawValue
switch deviceOrientationRaw {
case 1:
deviceOrientation = "Portrait"
case 2:
deviceOrientation = "Upside Down"
case 3:
deviceOrientation = "Landscape Right"
case 4:
deviceOrientation = "Landscape Left"
case 5:
deviceOrientation = "Camera Facing Down"
case 6:
deviceOrientation = "Camera Facing Up"
default:
deviceOrientation = "Unknown"
}
return deviceOrientation
} else {
return nil
}
}