Takahiro Octopress Blog

-1から始める情弱プログラミング

Universalアプリ開発における縦横対応について

iPhoneは縦のみ対応/iPadは縦横対応させたい!!

さて、久々に基本的なところで躓いてしまったのでメモしておきます。iPhone/iPadの両方に対応したUniversalなアプリを開発するときに、縦横対応を考える必要があります。iPhoneであれば基本的には縦もしくは横どちらかに固定すれば十分です。一方でiPadは縦をメインとして使うユーザと横をメインとして使うユーザの両方がターゲットとなります。では、iPhone/iPadで固定/非固定を分けて開発するためにはどうしたら良いのでしょうか?

今回はその答えを始めに紹介し、続いて筆者が躓いたことによって得た情報を紹介したいと思います。

では、始めにiPhone/iPadで固定/非固定を分けて開発する方法を紹介しましょう。
Xcode5上でTARGETS > Deployment Infoを見て下さい。iPhoneとiPadの文字が並んで表示されている部分があると思います。(恐らく、iPhoneが青字になっていることでしょう。)
この下にDevice Orientationと書かれており、Portrait, Upside Down, Landscape Left, Landscape Rightの4つのチェックボックスがあります。
iPhoneは縦のみ, iPadは全方向OKにしたい場合は、iPhone選択時にPortraitのみにチェック, iPad選択時に4つ全てにチェックを入れましょう。
Xcode5で各デバイスの設定をしましょう

これで設定完了です。非常に簡単ですね!
筆者はソースコードでどうにかしようと取り組んでいたため、時間がかかってしまいました笑。
ただ、逆に言えばソースコードでも設定は可能なんです。そこについて紹介しましょう。

まず、筆者は下記のようにAppDelegate.mファイルにソースを書きました。

1
2
3
4
5
6
7
8
9
10
11
12
13
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  self.window.backgroundColor = [UIColor whiteColor];

  // UIViewController型のViewControllerを生成
  ViewController *vc = [[ViewController alloc] init];
  vc = (ViewController *)[[NavigationController alloc] initWithRootViewController:vc];
  self.window.rootViewController = vc;
  [self.window makeKeyAndVisible];

  return YES;
}

objective-c NavigationControllerをrootViewControllerに指定しています。そのNavigationControllerに自身で作成したViewControllerを加えています。
さて、続いてViewController.mのソースを書いていきます。Objective-Cでは端末が回転したときにsupportedInterfaceOrientationsshouldAutorotateの2つが呼び出されます。
supportedInterfaceOrientationsは回転を許可する端末の方向を指定し, shouldAutorotateは端末が回転したときに自動で回転するかどうかを指定します。
例えば、

1
2
3
4
5
6
7
8
9
10
11
12
13
- (NSInteger)supportedInterfaceOrientations
{
  return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotate
{
  if(self.interfaceorientation == UIInterfaceOrientationPortrait) {
      return YES;
  } else {
      return NO;
  }
}

と書くと、supportedInterfaceOrientationsではPortrait方向のみ回転を許可し、shouldAutorotateではPortrait方向のみ自動で回転するようになっています。この両関数の指定がずれた場合はエラーが発生します。
上記のように書いておけば、冒頭で説明したXcode5のDevice Orientationの4つ全てにチェックを入れていたとしても、回転することはありません。
のはずでしたが、まだこの状態では回転してしまいます…。なぜなんでしょうか?
それはrootViewControllerにNavigationControllerを設定しまったためだそうです。これを回避するためには、NavigationControllerに設定してあるtopViewControllerの値を返すようにCustomNavigationControllerを作成する必要があります。
では、UINavigationControllerを継承したCustomNavigationControllerを作成しましょう。

1
2
3
4
5
// CustomNavigationController.h
#import <UIKit/UIKit.h>
@interface CustomNavigationController : UINavigationController

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#import "CustomNavigationController.h"

@interface CustomNavigationController ()

@end

@implementation CustomNavigationController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if(self) {
      // Custom initialization
  }

  return self;
}

- (void)viewDidLoad
{
  [supper viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];
}

// 新たに加えるソースは下記4行のみです。
- (NSInteger)supportedInterfaceOrientations
{
  return self.topViewController.supportedInterfaceOrientations;
}

@end

ここまで書ければ、後はAppDelegate.mファイルでNavigationControllerとしていたところをCustomNavigationControllerに変更すればOKです。
今度こそ、端末の回転を抑制することができていますよね?

今回は初歩的な話でしたが(いつもか…笑)、基本は非常に重要であり、知っていないと思わぬところで時間をくってしまいます。
様々な書籍でObjective-Cの基本的な書き方, Xcodeの基本的な使い方が紹介されていると思いますが、筆者のおすすめは下記。
WEB DB PRESSで初めてiOS7について基本的なところを説明してくれています。初心者には役に立つこと間違いないでしょう。Software Design Plus iOSアプリ エンジニア養成読本はまだ未発売ですが、iOSアプリのエンジニアとして生き残るための方法が書いてあるとのことなので、今から楽しみにしています。といったところで本日はここまで。

Comments