小嶋秀樹 | 研究室
日本語 | English

ここでは,Stanford 大学での授業で課された宿題(assignment)を解説します.一部アレンジしたものもあります.ぜひ自分でやってみてください.資料は英語ですが,内容は十分に理解できると思います.質問があれば TA か小嶋までどうぞ.

裏道場(1)
【1A. Hello MYU!】
1A. Hello MYU!

プログラムを書かないでアプリを開発します.右図のような画面を表示するだけのシンプルなアプリです.

  1. Xcode で Window-based Application を新規作成します.名前はたとえば HelloMYU としましょう.
  2. Resources から MainWindow.xib を開いて,Interface Builder を起動します.Tools > Library を開き,Label と Image View を Window にドラッグして配置します.
  3. Tools > Inspector で Label の Text 属性を「宮城大学へようこそ」にし,Font 属性などを調節します.大きさや位置を適当に調整してください.
  4. 宮城大学のシンボルマークの画像ファイルをダウンロードして,そのファイルを Resources にドロップしてください.(ドロップしたときのダイアログで "Copy ..." のチェックを入れるとよいです)
  5. Image View の属性 Image に,この画像ファイルを指定します.また Mode 属性を Aspect Fit に,Background 属性をWhite に設定します.Image View の大きさや位置を適当に調整してください.
  6. Interface Builder での変更を有効にするために File > Save します.
  7. Xcode のウィンドウに戻り,Build and Run を実行します.iPhone Simulator が起動し,右のような画面が出るはずです.
【1B. WhatATool (Part I)】
1B. WhatATool (Part I)

Mac OS X の上で動作するコンソールアプリです.Objective-C や Foundation の使い方に慣れることが目的です.ここでは,その手がかりだけをヒントとして解説します.Stanford 大学の資料に沿ってプログラミングを進めてください.

  1. Xcode で Mac OS X の Application を Command Line Tool(Type は Foundation)として新規作成します.名前はたとえば Assignment1b としましょう.
  2. Assignment1b.c を開くと main という関数が用意されています.これを Stanford の資料に沿って書き換えていきます.
  3. たとえば NSString についての情報を調べたいときは,Xcode > Help > Developer Documentation を開き,右上の検索窓に NSString と入れてください."Working with Paths" についての情報は,左側にある目次メニューから Task を展開し,該当する項目をクリックします.さらに調べたい項目(たとえば stringByExpandingTildeInPath)をクリックすれば,その詳細情報が得られます.
  4. プログラムを実行するには,Xcode > Run > Console を開き,そこで "Build and Run" をクリックしてください.NSLog の出力は,この Console に出力されます.

(ヒント)Section 1(ホームフォルダへのパスを表示)と Section 2(プロセス情報の表示)は,およそ次のようなプログラムになります.赤字は書き加えた部分です.他の Section についても,Developer Documentation を参考にしながら,Stanford 大学の資料に沿って,プログラムを作成してください.

#import <Foundation/Foundation.h>

void  PrintPathInfo ()
{
    NSString *path = @"~/";
    NSString *full = [path stringByExpandingTildeInPath];
    NSLog(@"My home folder is at '%@'", full);

    //  This is not a perfect answer...
    NSArray  *array = [full pathComponents];
    for (int i = 0; i < [array count]; i++) {
        NSLog(@"%d: %@", i, [array objectAtIndex:i]);
    }
}

void  PrintProcessInfo ()
{
    NSProcessInfo *pinfo = [NSProcessInfo processInfo];
    int pid = [pinfo processIdentifier];
    NSLog(@"Process ID is %d", pid);
}

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    PrintPathInfo();            // Section 1
    PrintProcessInfo();         // Section 2
    //PrintBookmarkInfo();      // Section 3
    //PrintIntrospectionInfo(); // Section 4

    [pool drain];
    return 0;
}
裏道場(2)
【2A. WhatATool (Part II)】
1B. WhatATool (Part II)

1B の続きです.新しいクラス(PolygonShape)をつくることにチャレンジします.完成した 1B のプロジェクトを開き,そこに新しい機能を加えていきます.

  1. File > New File... を選択し,Mac OS X > Cocoa > Objective-C class を開きます.名前は PolygonShape.m としましょう.ヘッダファイルも同時生成するようにチェックを入れておきます.このクラスは,正多角形の形状を扱うためのものです.
  2. Stanford 大学の資料の Section 5 に沿って,プログラミングを進めてください.
  3. PolygonShape クラスを書いたら,まずは Assignment1b のプロジェクトをビルドし,文法エラーなどがないかチェックしてください.
  4. エラーがなければ,つぎに Assignment1b.m を書き換え,Section 6 の説明に沿って,プログラミングを進めてください.その核心部分は,およそつぎのようになります.
        // Section 6
        NSMutableArray *mar = [[NSMutableArray alloc] init];
        PolygonShape *ps1 = [[PolygonShape alloc] init], 
                     *ps2 = [[PolygonShape alloc] init], 
                     *ps3 = [[PolygonShape alloc] init];
    
        [ps1 initWith...]; [mar addObject:ps1];
        [ps2 initWith...]; [mar addObject:ps2];
        [ps3 initWith...]; [mar addObject:ps3];
      
        NSEnumerator *enu = [mar objectEnumerator];
        PolygonShape *ps;
        while (ps = [enu nextObject])
            [ps setNumberOfSides:10];
      
        [ps1 release]; [ps2 release]; [ps3 release];
        [mar release];
    
    
    なお配列要素へのアクセスは,NSEnumerator を使わずに,for 文で配列の添字(0, 1, ..., [mar count])をスキャンすることでも可能です.

ヒントとして,PolygonShape.h のすべてと PolygonShape.m の骨格部分を書いておきます.参考にしてください.なお,angleInDegrees は頂点内角の角度を返します.

#import <Cocoa/Cocoa.h>

@interface PolygonShape : NSObject {
    int numberOfSides;
    int minimumNumberOfSides, maximumNumberOfSides;
}

@property int numberOfSides;
@property int minimumNumberOfSides;
@property int maximumNumberOfSides;
@property (readonly) float angleInDegrees;
@property (readonly) float angleInRadians;
@property (readonly) NSString *name;

- (id)initWithNumberOfSides:(int)num
       minimumNumberOfSides:(int)min
       maximumNumberOfSides:(int)max;
- (id)init;
- (void)dealloc;
- (NSString *)description;

@end
#import "PolygonShape.h"

@implementation PolygonShape

@synthesize numberOfSides;
@synthesize minimumNumberOfSides;
@synthesize maximumNumberOfSides;

- (id)initWithNumberOfSides:(int)num
       minimumNumberOfSides:(int)min
       maximumNumberOfSides:(int)max
{
    if (self = [super init]) {
        self.minimumNumberOfSides = min;
        self.maximumNumberOfSides = max;
        self.numberOfSides = num;
    }
    return self;
}

- (id)init
{
    return [self initWithNumberOfSides:5
                  minimumNumberOfSides:3
                  maximumNumberOfSides:10 ];
}

- (void)dealloc
{
    NSLog(@"A PolygonShape is going to be deallocated");
    [super dealloc];
}

// Implement the following methods yourself!
- (void)setNumberOfSides:(int)num {...省略...}
- (void)setMinimumNumberOfSides:(int)min {...省略...}
- (void)setMaximumNumberOfSides:(int)max {...省略...}
- (void)setNumberOfSides:(int)num {...省略...}
- (float)angleInDegrees {...省略...}
- (float)angleInRadians {...省略...}
- (NSString *)name {...省略...}
- (NSString *)description {...省略...}

@end
【2B. Hello Poly (Part I)】
2B. Hello Poly (Part I)

「2A. WhatATool (Part II)」の結果をふまえて,MVC(Model-View-Controller)デザインパターンにもとづく iPhone アプリに仕立てます.またグラフィック出力はありませんが,MVC の考え方を実践に結びつけてください.Stanford 大学の資料のとおり,Controller.h/.m を IB 上で自動生成してもよいですが,ここでは Xcode 上で書いていく方法を紹介します.

  1. Xcode > iPhone OS > Application > Window-based Application を新規作成します.名前は HelloPoly でよいでしょう.
  2. M をつくる:2A で作成した PolygonShape.h/.m を採り入れます.Xcode の Classes フォルダを右クリックして,Add > Existing Files... を選択し,PolygonShape.h/.m の両方を "Add" します.PolygonShape.h にある #import <Cocoa/Cocoa.h> を #import <Foundation/Foundation.h> に書き換えてください.
  3. V をつくる:IB 上で右図のようなユーザインタフェースをつくります.ラベルが1つとボタンが2だけのシンプルなインタフェースです.
  4. C をつくる:新しいクラス Controller.h/.m を作ります.Xcode > File > New File > Cocoa Touch Class > Objective-C class を選択し,ヘッダファイルとともに新規作成します.
  5. Controller.h には,ラベルやボタンへの IBOutlet をインスタンス変数として宣言し,ボタンが押されたときの IBAction(-increase, -decrease)も宣言しておきます.これに加えて,#import "PolygonShape.h" を加え,インスタンス変数に PolygonShape *polygonShape; を加えておきます.
  6. Controller.m には,-increase と -decrease の実装に加えて,-awakeFromNib の中で polygonShape オブジェクトを生成するようにします.いずれのメソッドについても,インタフェース(辺の数)を更新するようにしてください.(-updateInterface というメソッドを作って,それを [self updateInterface]; のように呼び出すとよいでしょう.)
裏道場(3)
【3. Hello Poly (Part II)】
3. Hello Poly (Part II) advanced

ここでは HelloPoly のグラフィック出力を実現します.5回目の道場「Views, Drawing, and Animation」で詳しく取り上げますので,Stanford 大学の資料と併せて,参考にしてください.ここではヒントだけをお伝えします.

  1. IB で UIView を Window にドラッグし,たとえば 280×280 の正方形に整え,多角形の描画オブジェクトとします.これを PolygonView というクラスのオブジェクトとして設定します,親クラスは UIView です.このオブジェクトを選択した状態で File > Write Class Files... を選択し,PolygonView.h/.m を自動生成します.
  2. Xcode に戻って Classes にこれらを入れてください.Controller.h に IBOutlet PolygonView *polygonView; のようにインスタンス変数を加えます.これが Controller から見える PolygonView オブジェクトです.
  3. IB で描画オブジェクトを Controller の polygonView に接続します.これで Controller から polygonView を制御できるようになります.
  4. polygonView.m の -drawRect を実装します.実際に多角形を描画するプログラムです.具体的には,(1) コンテクストを設定,(2) 必要ならば背景の塗りつぶし,(3) 最初の頂点からパスを開始,(4) 各頂点にパスを接続,(5) パスを閉じ,(6) 好きな色で Fill/Stroke となります.
  5. 多角形の名前("heptagon" など)は,UILabel を使って表示すると簡単です.Controller から「多角形の辺の数」の表示と連動して [polygonShape name] を表示させればよいでしょう.