如何在 Objective-C 中不旋转的视图控制器中检测设备的真实方向?

Posted

技术标签:

【中文标题】如何在 Objective-C 中不旋转的视图控制器中检测设备的真实方向?【英文标题】:How to detect real orientation of the device in a view controller which does not rotate in Objective-C? 【发布时间】:2021-09-08 08:08:04 【问题描述】:

我有一个始终处于纵向的视图控制器。有一个特定的功能根据设备本身的当前方向工作,而不是视图控制器的方向。 在这种情况下,如何检测设备的方向并在方向改变时触发功能?

【问题讨论】:

你的意思是你想知道重力相对于设备的方向吗?你可以尝试使用CMMotionManager.startDeviceMotionUpdates,从中得到gravity,这是一个3D向量。 您可以通过运行 CMMotionManager 来实现。 try this answer 【参考方案1】:

ios 8 开始,他们引入了 viewWillTransitionToSize,每次旋转都会触发

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
       [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) 
            UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
            // do what you need with orientation here
         completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) 
            
    ];
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

【讨论】:

【参考方案2】:

您可以通过运行 CMMotionManager 来实现这一点

#import <CoreMotion/CoreMotion.h>

#define DEGREES(x) (180.0 * x / M_PI)
#define RADIAN(x) (M_PI*x/180.0)
#define UPDATE_INTERVAL 0.3

typedef struct Point3D 
    CGFloat x, y, z;
 Point3D;

@interface DirectionListener()

    NSTimer * _motionTimer;
    CMMotionManager *_motionManager;

@end

@implementation DirectionListener

- (instancetype)init

    self = [super init];
    if (self) 
    

    
    return self;


- (void)dealloc 

    [self stopListenning];
    _motionManager = nil;
    if (_motionTimer) 
    
        [_motionTimer invalidate];
        _motionTimer = nil;
    


- (void)startListenning 

    if (_motionManager.deviceMotionActive) 
    
        return;
    
    if (!_motionManager) 
    
        _motionManager = [[CMMotionManager alloc] init];
        _motionManager.deviceMotionUpdateInterval = UPDATE_INTERVAL;
    
    [_motionManager startDeviceMotionUpdates];
    if (!_motionTimer) 
    
        _motionTimer = [NSTimer scheduledTimerWithTimeInterval:UPDATE_INTERVAL target:self selector:@selector(changeWithAttitude) userInfo:nil repeats:YES];
    


- (void)stopListenning 
    if (_motionManager.deviceMotionActive) 
    
        [_motionManager stopDeviceMotionUpdates];
        [_motionTimer invalidate];
        _motionTimer = nil;
    


-(void)changeWithAttitude 

    //get the value from motionManager there

【讨论】:

以上是关于如何在 Objective-C 中不旋转的视图控制器中检测设备的真实方向?的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C:如何将信号从视图发送到视图控制器以更改视图?

Objective-c 如何正确管理多个视图和控制器

如何使用objective-C在ios 9中隐藏特定视图控制器的状态栏

解雇 UIKeyboard 在 Objective-C 中不起作用

如何从objective-c类推送一个快速视图控制器并将数据传回并继续objective-c类中的下一个过程

如何在 Objective-C 控制器中以编程方式加载用 swift 编写的自定义 XIB 视图