我需要检测设备何时处于纵向方向,以便可以触发特殊的动画。但是我不希望我的观点自动旋转。
当设备旋转到纵向时,如何覆盖自动旋转的视图?我的应用程序仅需要以横向显示视图,但是如果我想能够检测到纵向旋转,似乎还需要支持纵向。
Answers:
当应用程序加载或视图加载时,尝试执行以下操作:
[[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的所有情况下,添加观察者时,也都应在适当的时间(可能(但并非总是如此)在视图出现/消失时)将其删除。您只能具有“成对”的观察/取消观察代码。如果不这样做,该应用程序将崩溃。选择观察/不观察的位置超出了此质量检查的范围。但是,您必须具有“取消观察”才能与上面的“观察”代码匹配。
如果您在寻找如何检测方向变化(不必一定要禁用旋转)时遇到了这个问题,那么您还应该知道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)
}
- (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];
}
1)David答案的Swift版本2)万一您仍然想在没有方向变化的情况下检测方向(Moe的Swift vesion关于我如何在iOS上检测设备方向的答案)
// 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())
directionChanged功能
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
}
}
如果您不想创建设备对象,也可以使用
-(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
}
}
首先禁用除所需方向以外的所有方向(以使其不旋转)
然后像David所说的那样,获取设备的当前方向:
另外,您也可以自己使用加速度计(因为它无论如何都是如此),并检查重力在哪里以查看其方向。如果您采用这种方法,则可以自己使用值来获得不同的结果。
.UIDeviceOrientationDidChange
即使设备没有旋转,通知也会在iPhone上多次调用。不知道原因,但是如果仅在设备真正旋转时才需要,请执行以下操作。
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中。
DeviceOrientation vs.ScreenSize vs StatusBar.isLandscape?
如果要检测背景方向的变化,并且还需要检测面朝上/朝下的变化,请检查此链接。在Swift中,如何在启动后立即正确获取设备方向?
它介绍了如何使用3种替代方法在Swift中正确检测方向:-viewWillTransitionToSize()-使用Observer-使用状态栏
viewDidLayoutSubviews
它会处理所有布局更改可能更现代。(回想一下,不久的将来,用户将在设备的Windows中调整应用程序的大小。)现在,响应式布局已成为常态。