UIImageViewに貼り付けた画像を回転させる方法

ユーザーがiPhoneを回転させた時に、UIImageViewに貼り付けた画像も同じように回転させる方法を以下に記載する。
1. シンプルなView-based Applicationの場合。

この場合は非常に簡単で、UIImageViewを管理するUIViewControllerのサブクラスでshouldAutorotateToInterfaceOrientationメソッドをオーバーライドし、YESを返すようにするだけである。これだけでUIImageViewに貼り付けた画像は自動的に回転してくれる。
また、UIImageViewのcontentModeをUIViewContentModeScaleAspectFitに指定しておく事で、画像サイズも適度に調節してくれる。

@interface ImageViewRotateTestViewController : UIViewController {
    UIImageView *rotateView;
}
@property (nonatomic, retain) IBOutlet UIImageView *rotateView;
@end
@implementation ImageViewRotateTestViewController
@synthesize rotateView;

- (void)viewDidLoad {
    [super viewDidLoad];
    rotateView.image = [UIImage imageNamed:@"test.jpg"];
    rotateView.contentMode = UIViewContentModeScaleAspectFit;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}
@end


2. TabBarApplicationの場合
TabBarApplicationの場合でもshouldAutorotateToInterfaceOrientationメソッドをオーバーライドし、YESを返すようにする事で画像の回転はサポート出来るのだが、一つだけ異なるのは、UIImageViewを管理するUIViewControllerのサブクラスだけでなく、各タブの全てのUIViewControllerのサブクラスでshouldAutorotateToInterfaceOrientationメソッドをオーバーライドし、YESを返すようにするという点である(Navigation-based Applicationでも同様)。
これにより以下のような形でユーザがiPhoneを回転されると、画像が自動的に回転してくれる。


3. TabBarApplicationでタブ部分は回転させない場合
最後にTabBarApplicationで以下のようにタブ部分は回転させず、画像だけを回転させる場合を考えてみる。

上記のような場合、shouldAutorotateToInterfaceOrientationメソッドをオーバーライドする方法は使えないため、iPhoneが回転した時に発生するNotificationを検知して、手動でUIImageViewを回転させるという方法を取る。
具体的な実装は以下のような感じで、CGAffineTransformを利用してUIImageViewを回転させている。

@implementation ImageViewRotateTestViewController
@synthesize rotateView;

- (void)viewDidLoad {
    [super viewDidLoad];
    // iPhoneが回転した時に発生するNotificationを検知するための処理
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didRotate:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];
    
    rotateView.image = [UIImage imageNamed:@"test.jpg"];
    rotateView.contentMode = UIViewContentModeScaleAspectFit;
}

// UIImageViewを回転させるための処理
// 回転を滑らかに行う場合にはアニメーションを付ける
- (void)rotateImageView:(CGFloat)angle {
    // CGContextRef context = UIGraphicsGetCurrentContext();
    // [UIView beginAnimations:nil context:context];
    // [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    // [UIView setAnimationDuration:0.5];
    [rotateView setTransform:CGAffineTransformMakeRotation(angle)];
    rotateView.frame = self.view.frame; // 画像サイズを適度に調節する場合に必要
    // [UIView commitAnimations];	
}

- (void)didRotate:(NSNotification *)notification {
    UIDeviceOrientation orientation = [[notification object] orientation];
    if (orientation == UIDeviceOrientationLandscapeLeft) {
        [self rotateImageView:M_PI / 2.0];
    } else if (orientation == UIDeviceOrientationLandscapeRight) {
        [self rotateImageView:M_PI / -2.0];
    } else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
        [self rotateImageView:M_PI];
    } else if (orientation == UIDeviceOrientationPortrait) {
        [self rotateImageView:0.0];
    }
}
@end

参考記事