2010年12月10日金曜日

変更される可能性のあるクラスのメソッドを呼び出す

任意のクラスのメソッドを呼び出すには下記のように

[testClass testMethod];

等と呼び出せば良いですが、例えば上記の「testClass」がプログラム実行中に動的に変更されてしまう場合は以下のようにします。


objc_object* ptrClass = testClass;
SEL ptrMethod = @selector(testMethod:);
[ptrClass performSelector:ptrMethod withObject:パラメータ]; // 呼び出し


ptrClass = testClass2; // 動的にクラスを変更
ptrMethod = @selector(testMethod2:); // 動的にメソッドを変更
[ptrClass performSelector:ptrMethod withObject:パラメータ]; // 呼び出し


C++に慣れた方であればポインタ変数を任意のクラスにキャストしてメソッド呼び出しを行いそうですが、Objective-Cでは上記のようにします。

なお、withObjectでパラメータを複数渡したい場合は、複数オブジェクトを格納するNSArrayオブジェクトを渡すようにします。
また、afterDelay:で秒数を指定すれば、任意の秒数後にメソッド呼び出しが行われます。

NULLとnil

NULLとnilはどちらも値としては同じ0のようです。

しかし、NULLはポインタに対して空という意味であり、
nilはオブジェクトに対して空という意味を表すそうです。

CやC++言語でBOOL型に0かFALSEを使いましたが、それと似たような感じです。
現状ではNULLでもnilでもどちらでも良さそうですが、今後問題とならないように、きちんと使い分けをしておいた方が良いかもしれません。

ところで、NSMutableArrayにnilを追加することはできないようですが、NSNullという空の意味を表すオブジェクトが用意されており、これを使えば追加することができるそうです。

2010年12月8日水曜日

独自のUIViewを作る

独自のUIViewを作るには、描画処理を独自に作成する必要があります。

UIViewでは描画を行う時に「drawRect:(CGRect)rect」メソッドが呼び出されます。

このメソッドをオーバーライドして独自の描画処理を行わせます。

独自のUIViewを作成するのは、割と低レベル(OSに近くなると言う意味)なことですので、C言語の関数で描画を行う必要があります。また、フォントの扱い等、多少クセがあるようです。


-(void)drawRect:(CGRect)rect
{
// 描画範囲を取得
CGRect parentViewBounds = self.bounds;

// ビューのコンテクストを取得
CGContextRef ctx = UIGraphicsGetCurrentContext();

// 塗りつぶし色設定
CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);

// 塗りつぶし色でビューを塗りつぶし
CGContextFillRect(ctx, CGRectMake(0, 0, parentViewBounds.size.width, parentViewBounds.size.height));

// 描画設定終了
CGContextClosePath(ctx);

// パスを描画
CGContextStrokePath(ctx);
}

UIViewのboundプロパティは、自身のUIViewの描画範囲をCGRect構造体で取得するプロパティです。

UIGraphicsGetCurrentContext()関数は、自身のUIViewインスタンスのコンテキストを取得する関数です。後の描画関数で引数として使用されます。

上記では、色の設定関数(CGContextSetFillColorWithColor)や塗りつぶし関数(CGContextFillRect)を呼び出していますが、実際の描画は最後に呼び出している描画関数(CGContextStrokePath)で行われます。色やパスの設定関数を呼び出した時点ではないことに少し注意が必要です。
例えば、色を何回変更してパスの設定を行ったとしても、実際の変更が行われるのはCGContextStrokePath等の描画関数を呼び出した時点ですので、途中の色設定は無視されて、最後の色設定のみが反映されることになります。

また、マウス操作などでリアルタイムに描画を変更したい場合などは、「setNeedsDisplayInRect」メソッドを呼び出せば、いつでもdrawRectメソッドがCallbackされます。

[self setNeedsDisplayInRect:self.frame];



描画を行う関数は大量にありますが、ほんの一部を抜き出すと、以下のようになります。
もっと知りたい方は、ドキュメントをCGContextで検索すればたくさん出てきます。

関数概要
CGContextAddLines線の描画設定
CGContextAddPathパスの描画設定
CGContextSetStrokeColorWithColor線の色設定
CGContextSetLineWidth線の太さ設定
CGContextSetFillColor塗りつぶし色設定
CGContextShowTextAtPointテキストの設定
CGContextSelectFontフォントの設定

上記表は描画関数のほんの一部です。上記表にはありませんが、イメージを描画したり、カーブ線を描画する関数もあるようです。

2010年12月1日水曜日

経過時間を取得する

経過時間を取得するには、以下のようにします。


NSDate* startTime = [[NSDate alloc] init];



NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:startTime];

timeに経過秒数が格納されます。