コードによる回転の制御
どうもiOS6あたりから制御方法が変わったらしい。
それまではshouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
メソッドで制御していたが、今はふたつのメソッドで制御するぽい。
//ここで回転していいかの判別をする
- (BOOL)shouldAutorotate
{
if (/* なにがしかの回転していいかの判定処理 */) {
return YES;
}
return NO;
}
//どの方向に回転していいかを返す(例ではすべての方向に回転OK)
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
ちなみに回転のタイミングでなにかしたい場合。
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
//回転時に処理したい内容
}
shouldAutorotateが呼ばれない場合
こちらの記事に書いてありました。
記事では、self.window.rootViewController
に、自分で作成したUINavigationController
を設定していると動作しないようです。
回転をコードから制御したい場合は、UINavigationControllerのサブクラスを作り、そちらに上記デリゲートメソッドを実装することで制御可能なようです。
サンプルコード
@interface HogeNavigationController : UINavigationController
@end
/////////////
@implementation HogeNavigationController
- (BOOL)shouldAutorotate
{
return YES; // or NO
}
- (NSUInteger)supportedInterfaceOrientations
{
// ポートレイトだけ許可
return UIInterfaceOrientationMaskPortrait;
}
@end
UINavigationControllerのカテゴリで対処する
ただ、回転のためだけに継承するのもあれなので、ということでカテゴリで対応する方法のほうがスマートかもしれません。
【UINavigationControllerの子ViewControllerにも回転イベントを伝える】
これには、カテゴリによる拡張を使うことでシンプルに解決できます。
@implementation UINavigationController (Rotation)
- (NSUInteger)supportedInterfaceOrientations
{
return [self.viewControllers.lastObject supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
return [self.viewControllers.lastObject shouldAutorotate];
}
@end
参考
解説
UINavigationControllerのカテゴリで回転に関するdelegateをオーバーライドします。
その上で、自身のviewControllers
の最後のViewControllerにも回転系のメッセージを送ります。
理由としては、( 上記リンクの下の記事を見てもらうと分かりますが )仕様的にrootViewController
にUINavigationControllerが設定されている場合、その子ViewControllerには回転系のメッセージは送られないようです。
そのために、カテゴリで拡張し、最後ViewControllerの(つまり現在表示されてる)ViewControllerにメッセージを送っている、というわけです。
イベントの発生順
shouldAutorote
supportedInterfaceOrientations
willRotateToInterfaceOrientaion:duration:
起動時の取得
起動時の画面の向きを取得するには、UIViewControllerのプロパティinterfaceOrientation
を利用すればいいようです。
UIInterfaceOrientation direction = self.interfaceOrientation;
if(direction == UIInterfaceOrientationPortrait){
// 縦(ホームボタンが下)
}
else if(direction == UIInterfaceOrientationPortraitUpsideDown){
// 縦(ホームボタンが上)
}
else if(direction == UIInterfaceOrientationLandscapeLeft){
// 横(ホームボタンが左)
}
else if(direction == UIInterfaceOrientationLandscapeRight){
// 横(ホームボタン右)
}