日々精進

新しく学んだことを書き留めていきます

画面回転ロックが設定されていても強制的に画面を回転可能にする方法

iOSが認識している端末の向きを縦に固定し、加速度センサを使って端末の向きを判定しAffintransformで画面を回転させる。
参考:iphone - iOS device orientation disregarding orientation lock - Stack Overflow
 iphone - Rotating Accelerometer output to new "neutral" for iOS, (and others). - Stack Overflow
大体↓のような感じ。

#define kFilteringFactor 0.05
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};

@interface ViewController ()
- (IBAction)touchLandscape:(id)sender;

@property(nonatomic, assign) UIAccelerationValue accelerationX;
@property(nonatomic, assign) UIAccelerationValue accelerationY;
@property(nonatomic, assign) float currentRawReading;
@property(nonatomic, assign) float calibrationOffset;
@property(nonatomic, assign) float rotationAngle;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
    accel.delegate = self;
    accel.updateInterval = 1.0f/60.0f;
}


-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
    self.accelerationX = acceleration.x * kFilteringFactor + self.accelerationX * (1.0 - kFilteringFactor);
    self.accelerationY = acceleration.y * kFilteringFactor + self.accelerationY * (1.0 - kFilteringFactor);

    self.currentRawReading = atan2(self.accelerationY, self.accelerationX);
    self.rotationAngle = -RadiansToDegrees(self.currentRawReading);

    // 縦向きの時はrotation=90
    if (80 < self.rotationAngle && self.rotationAngle < 100) {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    } else if (-10 < self.rotationAngle && self.rotationAngle < 10) {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
    } else if (170 < self.rotationAngle && self.rotationAngle < 190) {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return 0;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
//    return (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
    return YES;
}

- (IBAction)touchModal:(id)sender {
    ModalViewController *modal = [[ModalViewController alloc] init];
    modal.modalPresentationStyle = UIModalPresentationFullScreen;
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:modal];
    navigationController.navigationBarHidden = YES;

    [self presentViewController:navigationController animated:YES completion:nil];
}

- (IBAction)touchAlert:(id)sender {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"test" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
    [alert show];
}

- (IBAction)touchPortrait:(id)sender {
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}

- (IBAction)touchLandscape:(id)sender {
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
}