LoginSignup
9
9

More than 5 years have passed since last update.

[Objective-C] UIViewControllerの回転を自力でやる

Last updated at Posted at 2014-03-15

なんか他にもっとスマートなやり方がある気がしているけど、とりあえずこうした、というメモ。

要件

今回やりたかったことは、

  • UINavigationControllerのnavigationBarも含めた、画面全体を覆うように半透明の黒いビューを表示する
  • その上にメニューとなるボタンを出し、そして回転に対応すること。

この「回転に対応する」という部分に苦労しました。
今回やった対応は以下の感じです。

対応した内容

まず、UIViewControllerを継承したサブクラス(CustomViewController)を作ります。
その上で、メインとなるViewControllerからこのサブクラスを生成します。
ただ、メインのViewControllerはUINavigationControllerの子ViewControllerなので、これにaddChildViewController:で追加してしまうとnavigationBarの中に入ってしまいます。

windowのsubViewに

そこで、以下のようにしてwindowのsubViewにしました。

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

UIWindow *window = nil;

if ([appDelegate respondsToSelector:@selector(window)]) {
    window = [appDelegate window];
}
else {
    window = [[UIApplication sharedApplication] keyWindow];
}

CustomViewController *cvc = [[CustomViewController alloc] init];
[window addSubview:cvc.view];

回転処理

回転処理は、メインのViewControllerの回転に関するデリゲートメソッドをオーバーライドし、そのタイミングで以下のようにwindowに追加したViewControllerのviewを操作しました。

// CustomViewController側
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [UIView animateWithDuration:duration
                     animations:^{
                         CGRect frame = self.coverView.frame;
                         frame.size.width  = self.view.bounds.size.width;
                         frame.size.height = self.view.bounds.size.height;
                         self.coverView.frame  = frame;
                         self.coverView.center = self.view.center;

                         switch (toInterfaceOrientation) {
                             // 通常の状態
                             case UIInterfaceOrientationPortrait: {
                                 self.coverView.transform = CGAffineTransformMakeRotation(0);
                                 break;
                             }
                             // デバイスの左側が上の状態
                             case UIInterfaceOrientationLandscapeLeft: {
                                 self.coverView.transform = CGAffineTransformMakeRotation(-M_PI / 2);
                                 break;
                             }
                             // デバイスの右側が上の状態
                             case UIInterfaceOrientationLandscapeRight: {
                                 self.coverView.transform = CGAffineTransformMakeRotation(M_PI / 2);
                                 break;
                             }
                         }
                     }];

}

self.coverViewが、半透明の黒いビューの部分です。
これにボタンなどのメニューがsubViewとして追加されています。

上記のコードでこのcoverView自体は回転しますが、見てもらうと分かる通りwidth/heightを操作しているので、subViewの位置がずれてしまいます。
なので、上記以外にもsubViewの位置も合わせて調整してやる必要があります。

本当は独立したViewControllerにも回転の制御を指定できればいいんですが・・・。

ちなみにこちらの記事を参考にさせていただきました。
また、位置についてはこちらの記事が参考になりました。

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9