[PR]
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
データ関係のオブジェクト
ブログの編集ウインドウで編集するよりは長文の場合でも全体が見渡しやすく楽ですが、スタイルの設定や改行のチェックをしなくて良いのはブログの方が便利ですね。コードをそのまま貼り付けなどという手抜きも出来ましたし(おいおい…)。あとはNSMutableStringとNSNumberくらいは説明しないと駄目だろうな、などと考えています。
現在ホームページの改装工事中です
Tiny3D 2.0 配信開始しました
自分のアプリケーションのデータを標準のメールで送る
私も自分のアプリケーションが持つデータを外へ出すために四苦八苦し、自前でSMTPやFTPのクライアント機能を実装してなんとか出口を作ってきました。ですがこれからはそんな苦労をしなくても簡単にメール添付でのデータ送信ができます。それは3.0ではMessageUIが追加されたからです。実際の利用方法はアップル提供のサンプル「MailComposer」を詳しく見れば分かると思います。簡単に説明すると、まずメール送信のビューへ進みたいビューのコントローラーのヘッダファイルへ
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
を追加し、さらにMFMailComposeViewControllerDelegateに反応させるようにします。あとはメソッドファイル側でMFMailComposeViewController*型の変数を作り、必要なら宛先やCC、BCCの情報をそれぞれNSArrayにして渡します。さらに添付データをNSDataで、本文をNSStringで渡します。最後にこのメール編集用のコントローラーを表示させます。
メールを送信したか等の結果は
で受け取ります。当たり前ですがMessageUI.frameworkの追加は忘れずに行いましょう。MailComposerのプロジェクトを開いておいて、自分のプロジェクトへドラッグアンドドロップしてしまうのが簡単で良いと思います。
起動時のステータスバーの状態を変更する
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES];
[application setStatusBarHidden:YES animated:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
ステータスバーのスタイルは今選択されている行の右にあるプラス部分をクリックして行を増やし、キーにUISatusBarStyleと入力してエンターを押し、値には先ほどの3つのどれかを指定します。ステータスバーを隠した状態で起動させたい場合はキー部分にUIStatusBarHiddenと書いてエンターキーを押せば、値の部分にチェックボックスが表示されるので、そのチェックを外しておけばOKです。
現在の3.0用のSDKで作ったプロジェクトの場合、このように指定しようとキーを記入すると、キーが勝手にStatus bar styleやStatus bar is initially hiddenという名称に変更されます。その場合はスタイルの値をGray style (default)、Transparent black style (alpha of 0.5)、Opaque black styleの中から選びます。
ステータスバーのスタイルで透過を選んだ場合、ステータスバーの背後にDefault.pngの画像が透けて表示されます。スクリーンショットをそのまま使っている場合などは、ステータスバーの部分を白く塗りつぶすなど編集しておきましょう。そのままの状態にしておくと、スクリーンショットのステータスバーが現在のステータスバーの背後に重なって表示されてしまいます。
UITableViewControllerはどこへ行った?
UIViewControllerのアイコンだけがそのまま残されているため、ぱっと見で今までの選択用アイコンがインストールに失敗して消えてしまったかのように思えます。私はしばらくの間これで大丈夫なのかと不安になりました。でもこれでは別に異常ではなく、正常な状態のようです。ではUITableViewController subclassやUITableViewCell subclassなどはどこに行ってしまったのでしょうか。
iPhone OS 3.0 におけるセルの変更点
左にある画像が4種類のスタイルをそれぞれ適応したセルです。一番上がUITableViewCellStyleDefaultです。textLabelだけ表示される、今までに近い形の表示です。次がUITableViewCellStyleValue1です。タイトルと値を表示しますが、セルの幅を全て使う表示になります。その次がUITableViewCellStyleValue2です。タイトルと値が寄せて表示されます。最後がUITableViewCellStyleSubtitleです。2つのラベルが上下に並んで表示されます。ちなみに画像もこれまでは「セルの変数名.image」でしたが、「セルの変数名.imageView.image」となります。画像はスタイルがUITableViewCellStyleDefaultとUITableViewCellStyleSubtitleの場合だけラベルの左に挿入されます。
以下は上のスクリーンショットを撮影するのに使ったコードです。Navigation-based Applicationを選んでRootViewController.mの該当箇所をこのコードのように書き換えれば同じように表示されるはずです。Xcodeにそのままコピー&ペーストできるようにレイアウトはいじっていません。なお、これだけ少数のセルなので表示は全く問題ないはずですが、一応複数種のセルを使っていることもあるので、以前の記事『数種類のセルを使用してもスクロール速度の低下を極力減らす方法』と同じ書き方にしてあります。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 行ごとに表示を変更します。
switch (indexPath.row) {
case 0: {
UITableViewCell *cellDefault = [tableView dequeueReusableCellWithIdentifier:@"cellDefault"];
if (cellDefault == nil) {
cellDefault = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellDefault"] autorelease];
}
cellDefault.textLabel.text = @"textLabel";
return cellDefault;
}
break;
case 1: {
UITableViewCell *cellValue1 = [tableView dequeueReusableCellWithIdentifier:@"cellValue1"];
if (cellValue1 == nil) {
cellValue1 = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellValue1"] autorelease];
}
cellValue1.textLabel.text = @"textLabel";
cellValue1.detailTextLabel.text = @"detailTextLabel";
return cellValue1;
}
break;
case 2: {
UITableViewCell *cellValue2 = [tableView dequeueReusableCellWithIdentifier:@"cellValue2"];
if (cellValue2 == nil) {
cellValue2 = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:@"cellValue2"] autorelease];
}
cellValue2.textLabel.text = @"textLabel";
cellValue2.detailTextLabel.text = @"detailTextLabel";
return cellValue2;
}
break;
case 3: {
UITableViewCell *cellSubtitle = [tableView dequeueReusableCellWithIdentifier:@"cellSubtitle"];
if (cellSubtitle == nil) {
cellSubtitle = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellSubtitle"] autorelease];
}
cellSubtitle.textLabel.text = @"textLabel";
cellSubtitle.detailTextLabel.text = @"detailTextLabel";
return cellSubtitle;
}
break;
}
UITableViewCell *cellDefault = [tableView dequeueReusableCellWithIdentifier:@"cellDefault"];
if (cellDefault == nil) {
cellDefault = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellDefault"] autorelease];
}
return cellDefault;
}
2010年5月23日補足:
最後の実際に使われない部分はreturn nil;でもセル数との整合性が失われていなければ全く問題ないのですが、例えばtableView:numberOfRoawsInSection:で戻る値を4から5に変更するとここで空のオブジェクトが返り、結果としてアプリケーションが強制終了されてしまいます。そのような場合でも一応セルオブジェクトを返す事によりアプリケーション全体が落ちるのを避けられるようにしているため、このような一見すると面倒な表記になっています。
巨大化したメソッドファイルをカテゴリを使って分離する
まず、新規で分離するファイルと同じ名前に、何か付け足したメソッドファイルを作ります。ヘッダファイルは作らないようにチェックは外しておきます。@implementationの部分に以下のように括弧でくくってカテゴリ名を付け足します。先ほどのファイル名に付け足すものというのはカテゴリ名にしておくと分かりやすいでしょう。
@implementation Tiny3DAppDelegate (dxf)
そして、その前の部分に移動するメソッドで必要なインポートや定義を書き加えます。そしてヘッダファイルの最後にある@endのさらに後ろにそのカテゴリに移動させるメソッドを宣言しておきます。書き方はこれまでにヘッダファイルでやっていたメソッドの宣言と同じです。違うのはその宣言部分の前後を
@interface Tiny3DAppDelegate (dxf)
@end
で挟むということだけです。括弧の中は先ほど書いたカテゴリ名と同じにします。あとは元からあったメソッドファイルから、新しく作ったメソッドファイルへとメソッドを移動します。これで巨大になったメソッドファイルを分割することができます。同じようにしてカテゴリを複数作れば、メソッドファイルを複数のファイルに分散させる事も出来ます。メッセージ類は今までと全く同じままで良く、オブジェクトの内外ともに書き換える必要はありません。ちゃんとカテゴリ内のメソッドへもメッセージが届きます。まあ、そのためにヘッダ側でメソッドを宣言しているわけですが。なお、オブジェクト内部の変数はこれまで通りヘッダファイルの元々のインターフェース内で宣言、@synthesizeも元からあるメソッドファイルへと書くようにしましょう。