忍者ブログ

[PR]

2025年03月03日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Tiny3D 1.0.0 リリースしました

2009年01月27日
Tiny3Dがアップルの承認をクリアし、App Storeに並びました。エンターテインメントのカテゴリーにあります。リリース日が24日になっているので、また埋もれてます。リリースの日付を変更してみたのですが、果たして反映されるのでしょうか。

App Storeを見に行きたい方はこちらのリンクからどうぞ

2009.01.28追記
日付の変更がされて27日に変わっています。現状ではPCのApp Storeでエンターテインメントのリリース順トップに表示されています。

2009.01.29追記
以前ブログでも発表いたしました半額セールですが、App Storeのエンターテインメントの項目でたまにリリース順リストから消えている(検索や直接リンクでの表示は可能でした)ことがあったため、ちょっとだけ延長して2009年2月4日までの実施とします。
PR

リリースが遅れます

2009年01月24日
以前の記事で審査待ちと報告したTiny3Dですが、ビデオ撮影を繰り返すうちに動作に問題がある部分が発見されたため、修正バイナリを何度か再アップロードしています。今後はとりあえず一度審査結果が出るまで待つことにしますが、これらの影響によりリリースに遅れが生じます。なお、3Dオブジェクトのサンプルビデオをホームページにアップロードしましたので、興味のある方は下のリンクからどうぞ。

Tiny3D サンプル(日本語ページ)

Tab Bar ControllerとNavigation Controller

2009年01月23日
Xcodeで新規作成時にTab Bar Applicationを選ぶと、画面の下にTab Barがあり、2つのビューを切り替えて表示できる状態になります。さて、ここでそれぞれのビューへの参照はどうすれば得られるのでしょう。これを考える時、Interface Builderがヒントになります。View Modeを中央のツリー表示に切り替えてみましょう。Tab Bar Controllerが一番上の階層にあります。その下にそれぞれのView Controllerがぶら下がっています。それぞれのView ControllerをNavigation Controllerに変えた場合には、Tab Bar Controllerが一番上にあるままで、その下がNavigation Controllerで、その下にView Controllerが配置されます。なお、Interface BuilderでのTab Bar Controllerは代表クラスにあるtabBarControllerのことです。それぞれのタブの項目は配列に格納されているので、例えば左から数えて2番目のタブの項目にあるView Controllerのid値は代表クラス内で表記するなら、

単なるView Controllerの場合:
[[tabBarController viewControllers] objectAtIndex:1]

Navigation Controllerの場合で今表示中扱いのViewのController:
[(UINavigationController *)[[tabBarController viewControllers] objectAtIndex:1] topViewController]

という具合になります。じゃあ代表クラス外ならどうなるかというと、以前の記事に書いたように、

Tiny3DAppDelegate *appDelegate = (Tiny3DAppDelegate *)[[UIApplication sharedApplication]delegate];


というような感じでまず代表クラスの参照を得てから、先ほどのtabBarControllerをappDelegate.tabBarControllerに置き換えて表記します。これまでに代表クラスのヘッダをインポートしていない場合には、忘れずにインポートしておきましょう。

一つ手前の階層のビューへ戻る

2009年01月22日
 前回の記事で、上の階層に戻るのにナビゲーションバーのバックボタンを使いました。でも、オプションの選択等で項目を選んだらすぐに元のテーブルに戻りたいこともあります。そんな場合には下記の方法を使います。先ほどのコードをそのまま利用して話を進めます。

  1. AnotherViewController.mでnumberOfRowsInSectionのreturnを0から1にする。
  2. 前回と同様、cellForRowAtIndexPathで「cell.text = @"back";」をreturnの上の行に追加する。
  3. didSelectRowAtIndexPathに「[self.navigationController popViewControllerAnimated:YES];」を追加する。

ビルドして進行すると、前回と同様にテーブルが表示され、項目のタップで下の階層に移動します。ここでテーブルの項目であるbackをタップすると、上の階層のテーブルに戻ります。実際のプログラムでの応用ではdidSelectRowAtIndexPath内で戻る前に選択内容を変数に保存したり選択に伴う処理を入れれば良いわけです。なお、これらのアクションをIBActionメソッドとしておきボタンのタップ等で実行するようにすれば、テーブルではないビューでも同様の動作を行わせることができます。

お手軽ナビゲーション方法

2009年01月22日
いままでに書いた記事で、テーブルの大まかな書式設定は理解できたのではないかと思います。そこで今回は、テーブルの項目を選択したら、右側にスクロールして下層に移動する方法を説明します。全部説明すると膨大な文量になってしまうので、ざっくりとポイントだけ説明します。

  1. Navigation-Based Applicationのプロジェクトを新規作成します。プロジェクト名は何でも構いません。
  2. RootViewController.mで、viewWillAppearのコメントアウトを外し、中に「self.title = @"abc";」を追加します。中括弧の中であれば行の順番は気にしなくて大丈夫です。
  3. numberOfRowsInSectionのreturnを0から1に変更します。
  4. その下のcellForRowAtIndexPathの「return cell;」とある行の上にある空白の行に、「cell.text = @"123";」と記述します。
  5. 左側のリストのClassにTableViewControllerを新規ファイルで追加します。名前はAnotherViewControllerとします。
  6. RootViewController.mで冒頭の「@implementation」の上の行に「#import "AnotherViewController.h"」を追加します。
  7. didSelectRowAtIndexPath内のコメントのうち下3行の「//」を消します。
  8. 左側のリストのResourcesにView XIBを新規ファイルで追加します。名前はAnotherViewとします。
  9. AnotherView.xibを開き、File's OwnerのクラスをIdentity InspectorでAnotherViewControllerに変更します。
  10. ライブラリからTableViewをドラッグ&ドロップで追加し、もともとあるViewは消します。追加したTableViewのdataSourceとdelegateをFile's Ownerに接続します。File's OwnerのviewをTable Viewに接続します。

ビルドして進行すると、タイトルがabcという名前のテーブルが表示されます。123という項目をタップすると、右にスクロールして別のテーブルが表示されます。abcと書いてあるボタンを押すと、左にスクロールして元のテーブルに戻ります。


テキストフィールド間の移動

2009年01月21日
ビュー内にテキストフィールドが複数ある場合、何も設定をしていないと、ユーザーは入力したいテキストフィールドをタップし、入力を行うという作業を繰り返すことになります。それでも動くので問題はないのですが、あまりスマートな入力方法とは言えません。そこで何か良い方法は用意されていないものかと調べてみました。そこで行き着いたのがキーボードのリターンボタンを使う方法です。XcodeとInterface Builderを行ったり来たりすることになりますが、わかりやすいように手順を追って説明すると次のようになります。例では2つの値xとyを入力するテキストフィールドがあると思ってください。

1.まずXcodeでビューのテキストフィールドと対応するポインタを、テキストフィールドの数だけヘッダファイルのビューコントローラーの中括弧内にIBOutretを頭に付けて記述します。
例:IBOutlet UITextField *xValueTextField;

2.先ほどの中括弧の終わった後で@endより前の部分にプロパティを記述します。先ほどのポインタと対応するようにします。
例:@property (nonatomic, readonly) UITextField *xValueTextField;

3.メソッドファイルの@implementationより下の部分に@synthesizeを記述します。これも名付けたテキストフィールドの数だけ行います。
例:@synthesize xValueTextField;

4.dealloc関数内にポインタの解放を記述します。これも名付けたテキストフィールドの数だけ行います。
例:[xValueTextField release];

5.少なくともヘッダファイルを保存してからInterface Builderでビューのnibファイルを開きます。

6.それぞれのテキストフィールドを紐付けし、先ほど付けたポインタ名とそれぞれのテキストフィールドを対応させます。次にはじめに入力を行うテキストフィールド(例ではxValueTextField)をクリックします。

7.Attributes InspecterのText Input TraitsにあるReturn KeyをNextにします。これでこのテキストフィールドをタップした際、表示するキーボードに「改行」ではなく「次へ」というボタンが表示されます。

8.一度Interface Builderを閉じてXcodeに戻ります。変更内容は保存しておきましょう。

9.ビューのヘッダに、関数の宣言を追加します。関数の名前は好きなものを付けてください。
例:-(IBAction)xNext;

10.メソッドファイルに関数の本体を追加します。この例では次のテキストフィールド(yValueTextField)を入力可能状態にする命令を入れてあります。
例:

-(IBAction)xNext {

[yValueTextField becomeFirstResponder];

}


11.やはり少なくともヘッダファイルを保存した後、Interface Builderを開いて先ほどのビューコントローラーの紐付け用のウインドウ(黒っぽい色のもの)を表示します。

12.Received Actionsに先ほど追加した命令があるので、はじめに入力を行うテキストフィールド(例ではxValueTextField)へ紐付けします。この時、イベントの種類としてDid End On Exitを選びます。

以上で操作は完了です。こうすることで、例の場合ははじめのテキストフィールドでキーボードの「次へ」をタップしたときにxNext関数が実行され、yValueTextFieldが入力可能状態となり、入力用のキーボードが表示されます。なお、はじめに入力状態にするテキストフィールドの指定は、例の場合だとViewWillAppear関数に、

[xValueTextField becomeFirstResponder];


と書いておけばビューが表示された時点でxValueTextFieldが入力可能状態になります。

代表クラスのポインタ取得

2009年01月19日
多数のビューをもつプログラムでは設定データの管理は代表クラスで一元管理したほうが解りやすいです。なぜならアプリケーション起動直後にデータの読み込みを行うのも、アプリケーション終了時にデータを保存するのもプロジェクトの〜AppDelegateクラスで行うのが基本的なお作法だからです。そのため代表クラスに設定値変更用の命令を用意しておき、ビュー側でデータを変更したらそれを呼び出して代表クラス側の値を逐次変更してゆきます。では、ビューから代表クラスのポインタを取得するにはどうするかというと、UIApplicationクラスにある命令を使います。

 

Tiny3DAppDelegate *appDelegate = (Tiny3DAppDelegate *)[[UIApplication sharedApplication]delegate];

[appDelegate setEdited];

 
 
これは現在実行中のプログラムの代表クラスを返す命令です。実際の呼び出しは、上のような形で行うことが多いです。なお、キャストを入れないとid型が返るので、コンパイル時に警告が出ます。また、当たり前ですがビューコントローラーのメソッドファイル(.mファイル)の頭の部分に、

#import "Tiny3DAppDelegate.h"

 
といったようにインポートを書き忘れないようにしましょう。なお、id型で受け取ってメッセージを送る書き方もできます。

id appDelegate = [[UIApplication sharedApplication]delegate];

objc_msgSend(appDelegate,@selector(finishDownload));

 
これはダウンロードが終わったときに代表クラスに終了を通知する際、コールバック関数内で使った例です。このメッセージを受け取ったら、代表クラスからビュー側へメッセージを送ってビュー側にも通知し、ダウンロードが終わった旨を画面に表示するようにする。そんなときに利用しました。

各セルにアクセサリーを設定する

2009年01月19日
テーブルの各セルの右側には、アクセサリーと呼ばれるパーツを配置することができます。これを実現するのに使うのがaccessoryTypeForRowWithIndexPath:です。とりあえず例によって実際のコードから引っ張ってきましたので、まずはそれを見てみましょう。

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath

{

return (self.editing) ? UITableViewCellAccessoryDetailDisclosureButton :

UITableViewCellAccessoryDisclosureIndicator;

}

 
さて、このコードでは編集ボタンが押されて編集状態にあるか、そうでないかでアクセサリーを切り替えています。編集モードではディテールディスクロージャーボタンという、青丸に>記号が入ったようなボタンが表示されます。編集モードでない時はディスクロージャーインジケーターという、灰色の>が表示されます。ちなみにアクセサリーの種類は以下の4種類です。

UITableViewCellAccessoryNone:何も表示しません。
UITableViewCellAccessoryDisclosureIndicator:灰色の>を表示します。
UITableViewCellAccessoryDetailDisclosureButton:青丸に>記号が入ったボタンが表示されます。
UITableViewCellAccessoryCheckmark:チェックマークを表示します。

なお、以前の記事「前回起動時の選択項目にチェックマークを付ける」に書いたように、セルのプロパティ(accessoryType)を直接設定する方法もあります。この命令は初期設定用として、表示してからの動的な変更にaccessoryTypeを使うようにすると良いでしょう。

2009年11月7日追記
iPhone OS 3.0以降では上記のtableView:accessoryTypeForRowWithIndexPath:は使用できません。今のところは一応動きますが、ビルド時に警告が出るようになります。この場合はtableView:cellForRowAtIndexPath:内でUITableViewCellのプロパティaccessoryTypeとeditingAccessoryTypeを用いて通常及び編集時のアクセサリーを設定すると良いでしょう。