检测 iOS UIDdevice 方向

我需要检测什么时候的设备是在纵向方向,以便我可以发射一个特殊的动画。但我不希望我的观点自动转换。

当设备旋转到纵向时,如何覆盖自动旋转的视图?我的应用程序只需要显示它的风景,但似乎我需要支持肖像也如果我想能够检测到旋转肖像。

58496 次浏览

如果我没理解错的话,你的应用只是横向的。你可以简单地在应用程序设置中指定它只是横向的,因此不需要担心旋转。该应用程序将开始在横向和停留在那里,无论如何定位 iPad。

尝试在应用程序加载或视图加载时执行以下操作:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];

然后添加以下方法:

- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
/* start special animation */
break;


case UIDeviceOrientationPortraitUpsideDown:
/* start special animation */
break;


default:
break;
};
}

以上内容允许您注册设备的方向更改,而无需启用视图的自动旋转。


注意

在 iOS 中的所有情况下,当您添加一个观察器时,也要在适当的时候删除它(当视图出现/消失时,可能会删除,但不总是删除)。只能有“对”的观察/非观察代码。如果你不这样做,应用程序将崩溃。选择观察/不观察的位置超出了本质量保证的范围。然而,您必须有一个“ unObserver”来匹配上面的“ Observer”代码。

首先,除了您想要的方向外,禁用所有的选项(这样它就不会旋转)

然后就像大卫说的,只需要知道设备的电流方向:

Https://developer.apple.com/library/ios/#documentation/eventhandling/conceptual/eventhandlingiphoneos/motionevents/motionevents.html

或者你可以自己使用加速度计(因为它是如何做到的) 检查重力的位置,看看它有什么方向。如果您采用这种方法,您可以自己处理这些值,以获得不同的结果。

1)大卫回答的快速版本 2)在没有方向改变的情况下,如果你仍然想要检测方向(Moe 对 如何在 iOS 上检测设备的方向?的回答是 Swift 版本)

    // Initial device orientation
let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
if(orientation == UIInterfaceOrientation.Unknown){
// code for Unknown
}
else if(orientation == UIInterfaceOrientation.Portrait){
// code for Portrait
}
else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
// code for Portrait
}
else if(orientation == UIInterfaceOrientation.LandscapeRight){
// code for Landscape
}
else if(orientation == UIInterfaceOrientation.LandscapeLeft){
// ode for Landscape
}


// To detect device orientation change
UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "orientationChanged:",
name: UIDeviceOrientationDidChangeNotification,
object: UIDevice.currentDevice())

改变函数

func orientationChanged(note: NSNotification)
{
let device: UIDevice = note.object as! UIDevice
switch(device.orientation)
{
case UIDeviceOrientation.Portrait:
// code for Portrait
break
case UIDeviceOrientation.PortraitUpsideDown:
// code for Portrait
break
case UIDeviceOrientation.LandscapeLeft:
// code for Landscape
break
case UIDeviceOrientation.LandscapeRight:
// code for Landscape
break
case UIDeviceOrientation.Unknown:
// code for Unknown
break
default:
break
}
}

如果你来到这个问题寻找如何检测方向变化(不一定想要禁用旋转) ,你也应该知道的 viewWillTransitionToSize,这是从 iOS 8。

来自 给你的快速示例

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {


coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in


let orient = UIApplication.sharedApplication().statusBarOrientation


switch orient {
case .Portrait:
println("Portrait")
// Do something
default:
println("Anything But Portrait")
// Do something else
}


}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
println("rotation completed")
})


super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

如果你不需要担心实际的入学方向:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {


// do something


super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Objective-来自 给你的 C 示例

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// do whatever
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{


}];


[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

如果你不需要担心实际的方向(取自 这个答案) :

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Do view manipulation here.
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

参见

如果不想创建设备对象,还可以使用

-(void) seObserverForOrientationChanging
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
}




- (void) orientationChanged:(NSNotification *)note
{
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
//Do something in landscape
}
else {
//Do something in portrait
}
}

即使设备没有旋转,在 iPhone 上也会多次调用 .UIDeviceOrientationDidChange通知。不知道原因,但如果你只需要它时,设备真正旋转,然后做到以下几点。

NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)

观察者调用的方法应该是这样的:

func orientationChanged() {


if traitCollection.isIphone {


defer {
self.previousTraitCollectionForIphone = traitCollection
}


guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {


updateView()
return
}


if previousTraitCollectionForIphone != traitCollection {
updateView()
}


} else {
updateView()
}
}

在 Swift 5.0中。

设备定位与屏幕大小对比 StatusBar.isscape? ?

如果你想检测背景方向的变化,并且还需要检测面向上/面向下的变化,请检查这个链接 在斯威夫特,如何得到正确的设备方向权后,它的启动?

它涵盖了如何正确地检测方向在 Swift 使用3种替代方法做到这一点: - viewWillTrantionToSize () - 使用观察者 - 使用状态栏

下面是一些额外的代码,以避免虚假的 UI 重置或过渡:

- (void) orientationChanged:(NSNotification *)note
{
UIDeviceOrientation newOrientation = ((UIDevice*)note.object).orientation;
    

// don't do anything if device is flat...
if (UIDeviceOrientationIsFlat(newOrientation) || newOrientation == UIDeviceOrientationUnknown)
return;
           

// ... and only if orientation has changed
if (newOrientation != self->lastOrientation) {
// do whatever you need to do to change UI
        

self->lastOrientation = newOrientation;
}
}