[英]iOS: Device orientation on load
似乎当我的应用程序加载时,它不知道它的当前方向:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
NSLog(@"portrait");// only works after a rotation, not on loading app
}
旋转设备后,我得到了正确的方向,但是当我加载应用程序时,在不更改方向的情况下,似乎使用[[UIDevice currentDevice] orientation]
不知道当前方向。
当我第一次加载我的应用程序时,还有其他方法可以检查吗?
编辑:我误读了你的问题。 这将允许您以特定方向启动应用程序。 刚刚意识到您正在尝试确定启动时的方向。
有一种方法可以检查UIApplication
上的状态栏方向:
[[UIApplication sharedApplication] statusBarOrientation];
尝试在 plist 文件中设置应用程序接受的设备方向:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
这将表明您的应用程序支持纵向(底部的主页按钮)、横向左侧和横向右侧。
然后,在您的 UIViewControllers 中,您需要重写shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
方法以在应用程序旋转时返回 YES:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}
如果设备处于您支持的方向之一,这将告诉 UIViewController 自动旋转。 如果您也想支持倒置方向(顶部带有主页按钮的肖像),请将其添加到您的 plist 中,然后在此方法中返回 YES。
让我们知道它是如何工作的。
我认为这会起作用:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;
根据 UIDevice 参考:
引用:
“除非已通过调用 beginGeneratingDeviceOrientationNotifications 启用了方向通知,否则此属性的值始终返回 0”
我最初假设此属性始终包含当前方向,但显然并非如此。 我猜想在通常访问方向属性的其他情况下,在幕后为我们处理打开通知,因此这需要在应用程序委托中手动完成并不明显
对于那些寻找 Swift 3 或 4 的答案的人。只需在 viewDidLoad() 块内添加该代码。
let orientation = UIApplication.shared.statusBarOrientation
if orientation == .portrait {
// portrait
} else if orientation == .landscapeRight || orientation == .landscapeLeft{
// landscape
}
IOS 13 和 Swift 5.x 的折旧警报更新使用下面的代码块。
if #available(iOS 13.0, *) {
let orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
if orientation == .portrait {
// portrait
} else if orientation == .landscapeRight || orientation == .landscapeLeft{
// landscape
}
} else {
// Fallback on earlier versions
let orientation = UIApplication.shared.statusBarOrientation
if orientation == .portrait {
// portrait
} else if orientation == .landscapeRight || orientation == .landscapeLeft{
// landscape
}
}
您可以通过在里面插入以下通知来做到这一点
-(void)viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
然后将以下方法放入您的 class
-(void)checkRotation:(NSNotification*)notification
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//Do your textField animation here
}
}
上述方法将检查 ipad 或 iPhone 的状态栏的方向,并根据它在所需的方向上执行 animation。
加载时,设备方向可以是.Unknown
或.FaceUp
。 为了弄清楚它是纵向还是横向,我使用statusBarOrientation
作为备份,如下所示:
var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait
if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
}
这样我可以确保 PortraitOrientation 总是告诉我设备是否处于portraitOrientation
模式,如果不是,它将处于横向模式。 即使是第一次加载应用程序。
还没有人提到的一件事是您将UIDeviceOrientation
类型存储在UIInterfaceOrientation
变量中。 它们是不同的,不应被视为平等。 请注意, UIDeviceOrientationLeft
等于UIInterfaceOrientationRight
(因为与设备相比,界面旋转的方式相反)。
为了从状态栏获取方向,在 plist 文件中启用所有方向也很重要。
Swift 3基于@Marjin 的代码。
var portraitOrientation = UIDevice.current.orientation == .portrait
if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}
if(portraitOrientation)
{
// Portrait
}
else
{
}
问题是[UIDevice currentDevice]orientation]
有时会错误地报告设备的方向。
而是使用[[UIApplication sharedApplication]statusBarOrientation]
这是一个UIInterfaceOrientation
所以要检查它你需要使用UIInterfaceOrientationIsLandscape(orientation)
希望这可以帮助。
我仍然将这个工作代码片段用于 iphone 4:
-(void)deviceOrientationDidChange:(NSNotification *)notification{
//Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
int value = 0;
if(orientation == UIDeviceOrientationPortrait)
{
value = 0;
}else if(orientation == UIDeviceOrientationLandscapeLeft)
{
value = 90;
}else if(orientation == UIDeviceOrientationLandscapeRight)
{
value = -90;
}
CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(value));
[photoImageView setTransform:cgCTM];
}
这是真正的答案。 当应用程序启动时,它的方向是未知的。 它使用 shouldAutorotateToInterfaceOrientation 和 supportedInterfaceOrientations 来决定选择哪个方向。
观看我在 iPhone 5.0 模拟器中启动示例应用程序并使用下面的代码和“支持的界面方向”以及所有 4 种可能的方向旋转它:
20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
我见过很多代码片段,但它们都不够通用(iPad 和 iPhone,iOS 5.0+)。
与其在 try-this-try-that 中摸索,不如将以下内容放在您的根 vc 中:
#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {
#define ToNSString_VALUE(value) \
case value: return @#value
#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}
// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait); // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft); // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight); // 4
ToNSString_END (UIInterfaceOrientation);
// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown); // 0
ToNSString_VALUE(UIDeviceOrientationPortrait); // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft); // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight); // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp); // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown); // 6
ToNSString_END (UIDeviceOrientation);
// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}
// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
static NSUInteger orientationsResult;
if (!orientationsResult) {
NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];
for (id orientationString in supportedOrientations) {
if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
orientationsResult |= UIInterfaceOrientationMaskPortrait;
NSLog(@"Supported orientation: Portrait");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
NSLog(@"Supported orientation: Portrait (upside-down)");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
NSLog(@"Supported orientation: Landscape (home button on the left)");
} else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
NSLog(@"Supported orientation: Landscape (home button on the right)");
} else {
NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
}
}
}
return orientationsResult;
}
// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
return result;
}
// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
NSString* orientationString;
UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
UIInterfaceOrientationToNSString(interfaceOrientation)
];
} else {
orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
];
}
BOOL result = [self allowAutoRotate:interfaceOrientation];
NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
result ? "YES" : "NO",
orientationString);
return result;
}
仍然存在不使用当前方向的 segue 动画的烦人问题。 我的猜测是,将每个 VC 子类化并在 pop 上放置一些方向/通知委托将是 go 的方式。
也很重要:
试试这个。 这对我有用。 粗糙的当时 didfinishedlaunch 方法没有检测到设备方向。 它默认为肖像。 所以。 我用来检查统计栏方向。 我测试这段代码。 把它放在appdeleget的didfinishedlaunch方法中。
UIInterfaceOrientation 方向 = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == 0) {//Default orientation
//UI is in Default (Portrait) -- this is really a just a failsafe.
NSLog("for portrait");
}else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
NSLog("portrait");
}else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
NSLog("Landscap");
}
试试这个[[UIApplication sharedApplication] statusBarOrientation];
或在应用程序委托中实现这个
(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}
有用
尝试使用加速度计来获取它的读数,UIAccelerometer,获取 sharedAccelerometer,设置它的委托,获取读数,从那里找出方向。
都试过了,没有好的结果。 因此,当我在 ipad 上时,我所做的就是将所有工作留给 splitViewController 方法来使 barButton 无效:
对于肖像:
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc { NSlog(@"portrait");}
对于风景:
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem{ NSlog(@"landscape");}
这始终适用于负载。
上面的每个人都发布了非常有效的答案:但作为更新:Apple 的看法:您应该使用 UIStatusBar 方向来读取设备的当前方向:
检查设备当前方向的一种方法是在viewDidLoad
方法中使用 int 值:
int orientationType = [[UIDevice currentDevice] orientation];
在哪里考虑以下内容。 . . - 1 = 纵向(右侧向上) - 2 = 纵向倒置 - 3 = 横向(右侧) - 4 = 横向(左侧)
然后您可以在检测到方向后使用IF
语句调用方法,依此类推:
希望这对某人有点帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.