Interface Builderを使わずにiPhoneアプリを作ってみる

Xcodeで、Interface Builderなしのテンプレートを作って、それを最低限動かす。
 

Window-based ApplicationをコピーしてInterface Builderなしのテンプレートを作る

多分こんな感じ。
Mac OS X 10.6.4 32bit、Xcode 3.2.2 64bit、の環境ではこれで出来た。

# ユーザテンプレートディレクトリを作成、移動
mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Application/
cd ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Application/

# Window-based Applicationをコピー
cp -r /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Project\ Templates/Application/Window-based\ Application/Window-based\ iPhone\ Application .
mv Window-based\ iPhone\ Application/ Empty\ iPhone\ Application
cd Empty\ iPhone\ Application/

# XIB削除
yes | rm MainWindow.xib

# Window設定削除
mv ___PROJECTNAMEASIDENTIFIER___-Info.plist ___PROJECTNAMEASIDENTIFIER___-Info.plist.org
cat ___PROJECTNAMEASIDENTIFIER___-Info.plist.org | sed '/NSMainNibFile/d' | sed '/MainWindow/d' > ___PROJECTNAMEASIDENTIFIER___-Info.plist
yes | rm ___PROJECTNAMEASIDENTIFIER___-Info.plist.org

# IBOutlet削除
mv Classes/___PROJECTNAMEASIDENTIFIER___AppDelegate.h Classes/___PROJECTNAMEASIDENTIFIER___AppDelegate.h.org
cat Classes/___PROJECTNAMEASIDENTIFIER___AppDelegate.h.org | sed 's/IBOutlet //' > Classes/___PROJECTNAMEASIDENTIFIER___AppDelegate.h
yes | rm Classes/___PROJECTNAMEASIDENTIFIER___AppDelegate.h.org

# XIB設定削除
mv ___PROJECTNAME___.xcodeproj/project.pbxproj ___PROJECTNAME___.xcodeproj/project.pbxproj.org
cat  ___PROJECTNAME___.xcodeproj/project.pbxproj.org | sed '/MainWindow\.xib/d' > ___PROJECTNAME___.xcodeproj/project.pbxproj
yes | rm ___PROJECTNAME___.xcodeproj/project.pbxproj.org

# Delegateファイル指定
mv main.m main.m.org
cat main.m.org | sed 's/nil, nil/nil, @"___PROJECTNAMEASIDENTIFIER___AppDelegate"/' > main.m
yes | rm main.m.org

 

最低限動かす

アプリケーション名は、"Untitled"で作った。
コントローラとビューを追加して、なんとなく作る。
この作り方が正しいのかは不明。
むしろ意味があるのかすら不明。
今後意味が出てくると思いたい。
 
構造を表すならこんな感じ…?

Application {
 UIWindow window {
  UIView view {
   viewController.view
  }
  RootViewController viewController {
   UIView view = RootView contentView {
    UILabel label1
   }
  }
 }
}

 

ファイル追加

コントローラ、RootViewControllerを追加。
ビュー、RootViewを追加。
 

UntitledAppDelegate.h

変数viewControllerを定義する。

#import <UIKit/UIKit.h>
#import "RootViewController.h"

@interface UntitledAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    RootViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) RootViewController *viewController;

@end

 

UntitledAppDelegate.m

self.windowを作る。
viewControllerを作る。
viewController.viewをSubViewに追加する。

#import "UntitledAppDelegate.h"

@implementation UntitledAppDelegate

@synthesize window;
@synthesize viewController;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch
    UIWindow *w = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [w setBackgroundColor:[UIColor whiteColor]];
    self.window = w;
    [w release];

    viewController = [[RootViewController alloc] initWithNibName:nil bundle:[NSBundle mainBundle]];
    [window addSubview:viewController.view];

    [window makeKeyAndVisible];

    return YES;
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}


@end

 

RootViewController.h

UIViewControllerを継承したRootViewControllerを定義。

#import <UIKit/UIKit.h>


@interface RootViewController : UIViewController {

}

@end

 

RootViewController.m

loadView内で、RootViewを作成してビューに代入。

#import "RootViewController.h"
#import "RootView.h"

@implementation RootViewController

/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
    }
    return self;
}
*/

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
    RootView *contentView = [[RootView alloc] initWithFrame:CGRectMake(0,20,320,460)];
    self.view = contentView;
    [contentView release];
}

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


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


@end

 

RootView.h

UIViewを継承したRootViewを定義。

#import <UIKit/UIKit.h>


@interface RootView : UIView {

}

@end

 
 

RootView.m

initWithFrame内でUILabelを作ってSubViewに追加する。
ここでやっと表示される。

#import "RootView.h"


@implementation RootView


- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
        NSLog(@"initWithFrame");
        UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
        [label1 setText:@"ABCDEFG"];
        [label1 setBackgroundColor:[UIColor redColor]];
        [label1 sizeToFit];
        [self addSubview:label1];
        [label1 release];
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

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


@end

 

参考URL

Interface Builderと決別・テンプレート作成

nibファイルを使わないテンプレートを作る(1)Window-Based Application - ねこじたclockwork
http://d.hatena.ne.jp/myomi/20090415/1239804053
 
Interface Builder を使わない iPhone アプリを作る手順 - WebOS Goodies
http://webos-goodies.jp/archives/how_to_create_an_iphone_app_without_interface_builder.html
 
InterfaceBuilderから決別するほうほう - haoyayoi Dev Style - iPhoneアプリ開発グループ
http://iphone-dev.g.hatena.ne.jp/hao_yayoi/20090414/1239717134
 
A-Liaison BLOG: Xcodeのテンプレートを作成する方法
http://akisute.com/2009/06/xcode.html
 

UIViewController

[iPhone] UIViewControllerの各メソッドの役割おさらい - Ni chicha, ni limona - 平均から抜けられない僕 - iPhoneアプリ開発グループ
http://iphone-dev.g.hatena.ne.jp/paella/20090629/1246291917