检测 iOS UIDevice 方向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9122149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting iOS UIDevice orientation
提问by Jace999
I need to detect when the device is in portrait orientation so that I can fire off a special animation. But I do not want my view to autorotate.
我需要检测设备何时处于纵向,以便我可以触发特殊动画。但我不希望我的视图自动旋转。
How do I override a view autorotating when the device is rotated to portrait? My app only needs to display it's view in landscape but it seems I need to support portrait also if I want to be able to detect a rotation to portrait.
当设备旋转到纵向时,如何覆盖自动旋转的视图?我的应用程序只需要以横向方式显示它的视图,但如果我希望能够检测到纵向的旋转,我似乎也需要支持纵向。
回答by David M. Syzdek
Try doing the following when the application loads or when your view loads:
尝试在应用程序加载或视图加载时执行以下操作:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Then add the following method:
然后添加以下方法:
- (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;
};
}
The above will allow you to register for orientation changes of the device without enabling the autorotate of your view.
以上将允许您注册设备的方向更改,而无需启用视图的自动旋转。
Note
笔记
In all cases in iOS, when you add an observor, also remove it at appropriate times (possibly, but not always, when the view appears/disappears). You can only have "pairs" of observe/unobserve code. If you do not do this the app will crash. Choosing where to observe/unobserve is beyond the scope of this QA. However you must have an "unobserve" to match the "observe" code above.
在 iOS 中的所有情况下,当您添加观察器时,也要在适当的时间将其删除(可能,但不总是,当视图出现/消失时)。您只能拥有“成对”的观察/不观察代码。如果您不这样做,应用程序将崩溃。选择观察/不观察的位置超出了本 QA 的范围。但是,您必须有一个“unobserve”来匹配上面的“observe”代码。
回答by Suragch
If you came to this question looking for how to detect an orientation change (without necessarily wanting to disable the rotation), you should also be aware of viewWillTransitionToSize
, which is available from iOS 8.
如果您遇到这个问题是为了寻找如何检测方向变化(不一定要禁用旋转),那么您还应该知道viewWillTransitionToSize
iOS 8 中提供的 。
Swift example from here
来自此处的Swift 示例
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)
}
And if you don't need to worry about the actual orientation:
如果您不需要担心实际方向:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// do something
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
Objective-C example from here
来自此处的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];
}
And if you don't need to worry about the actual orientation (taken from this answer):
如果您不需要担心实际方向(取自此答案):
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Do view manipulation here.
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
See also
也可以看看
回答by Tsuneyuki Ohsaki
1) Swift version of David's answer 2) In case you still want to detect orientation when there's no orientation change (Swift vesion of Moe's answer to How Do I detect the orientation of the device on iOS?)
1) David 答案的 Swift 版本 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())
orientationChanged function
方向改变函数
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
}
}
回答by drekka
If I understand you correctly, your app is landscape only. You can simply specify in the apps setup that it is landscape only and therefore do not need to worry about rotation. The app will start in landscape and stay there regardless of how the iPad is orientated.
如果我理解正确,您的应用程序仅适用于横向。您可以简单地在应用程序设置中指定它仅为横向,因此无需担心旋转。无论 iPad 的方向如何,该应用程序都将以横向模式启动并停留在那里。
回答by Pochi
First disable all but the orientation you want (so that it doesnt rotate)
首先禁用除您想要的方向之外的所有方向(以便它不会旋转)
Then like David said just get the device current orientation:
然后就像大卫说的那样获取设备当前的方向:
Alternatively you can just use the accelerometer yourself (since its how it is done anyway) and check where the gravity is at to see what orientation it has. If you take this approach you can play with the values yourself to get different results.
或者,您可以自己使用加速度计(因为它是如何完成的)并检查重力的位置以查看它的方向。如果您采用这种方法,您可以自己处理这些值以获得不同的结果。
回答by B.Kosmowski
If you do not want to create device object, you can also use
如果不想创建设备对象,也可以使用
-(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
}
}
回答by Bart?omiej Semańczyk
.UIDeviceOrientationDidChange
notification is called many times on iphone even when device did not rotate. Do not know the reason, but if you need it only when device really rotated, then do the following.
.UIDeviceOrientationDidChange
即使设备没有旋转,通知也会在 iphone 上多次调用。不知道原因,但如果您仅在设备真正旋转时才需要它,请执行以下操作。
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)
The method called from observer should look like this:
从观察者调用的方法应该是这样的:
func orientationChanged() {
if traitCollection.isIphone {
defer {
self.previousTraitCollectionForIphone = traitCollection
}
guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {
updateView()
return
}
if previousTraitCollectionForIphone != traitCollection {
updateView()
}
} else {
updateView()
}
}
回答by eharo2
In Swift 5.0.
在 Swift 5.0 中。
DeviceOrientation vs. ScreenSize vs StatusBar.isLandscape?
DeviceOrientation vs. ScreenSize vs StatusBar.isLandscape?
If you want to detect changes of orientation in background, and also need to detect face up/down changes, check this link In Swift, how to get the device orientation correctly right after it's launched?
如果您想检测背景中的方向变化,并且还需要检测面朝上/朝下的变化,请检查此链接在 Swift 中,如何在启动后立即正确获取设备方向?
It covers how to correctly detect the orientation in Swift using 3 alternate ways to do it: - viewWillTransitionToSize() - Using Observer - Using the status bar
它涵盖了如何使用 3 种替代方法在 Swift 中正确检测方向: - viewWillTransitionToSize() - 使用观察者 - 使用状态栏