More Related Content
Similar to I phoneアプリ入門 第4回 (20)
I phoneアプリ入門 第4回
- 2. 今後の予定
・第5回 TableView続き
・第6回 ユーザ操作(タップなど)の検出方法
現在地の取得方法
・第7回 MapKitを使った地図の表示方法
ブラウザでGoogleMapを表示する
13年3月17日日曜日
- 3. 今日のアジェンダ
・前回の復習
・protocolとdelegate
・テーブルビュー
・タイマー(一定時間ごとに処理を実行)
・サンプルアプリ作成
13年3月17日日曜日
今日のスケジュールは以下の通りです。
まず、前回の復習を軽く行った後、キーパッドの閉じかたとデリゲートについて勉強します。
その後、テーブルビューについて勉強します。
タイマーについては時間があったら行う予定です。
今日も手を動かしていきましょう。よろしくおねがいします。
- 4. 前回の復習
∼以下のようなアプリを作ってみましょう∼
動かすと文字色が変わる
押すと次の画面へ移動する
13年3月17日日曜日
まず、前回の復習をしましょう。
前回受講したという前提で、まずはコードを書いてみます。
図のようなアプリを作ってみましょう。
iPhone上でボタンを押したら次の画面が表示される
次の画面ではRGBをスライダーで設定し、設定した値が最初の画面に反映される
・前回やったシングルトンを使います。
何のことだかさっぱりわからないと言う方、こっそり教えてください・・・。
- 5. 前回勉強したこと
• 強い参照と弱い参照
→循環参照が発生するものにはweakを使う
• MVCモデル
→Model/View/Controllerの3つで役割分担
• シングルトン
→プログラム中でオブジェクトを一つだけもつ
13年3月17日日曜日
前回学習したことを少し思い出してみましょう
前回はこの3つのことについて勉強しました。
・強い参照と弱い参照
→Objective-Cはリファレンスカウンタ方式をとっており、オブジェクトが誰からも参照されなくなったら、メモリから解放
されるのですが、オブジェクト同士が参照し合っている場合はいつまでもメモリから解放されず、メモリリークを起こしてし
まいます。StoryBoardでviewに部品を配置する場合など、オブジェクト同士が参照し合う場合は弱い参照(weak)を使って
スコープ外のオブジェクトをメモリから消してしまいます。
MVCモデル
→Objective-CではMVCモデルを使って、Model/View/Controllerの3つで役割分担をしています。
Model:データの保持や更新を行う
View:Modelの内容を表示する
Controller:ユーザ操作を受け付けたり、Modelの操作を行う
・シングルトン
Javaでもよく出てくるデザインパターンで、オブジェクトを一つだけ持つものです。
- 6. protocolとdelegate
∼機能を追加しましょう∼
13年3月17日日曜日
では、ここで復習で作ったアプリに機能を1つ追加しましょう。
色の変更だけでなく、表示する文字列を変更するようにしてみましょう。
2番目に表示される画面で文字入力を行ってその結果を最初の画面に反映するようにしましょう。
2番目の画面ではテキストフィールドというものを使いましょう。
- 7. キーパッドを閉じるには
キーパッドが閉じないのは不便・・・
13年3月17日日曜日
使ってみて、不便に思ったことは無いでしょうか。
「キーパッドが閉じてくれない」
「入力してもすぐに反映してくれない」
この2つはキーパッドを閉じるという機能を実装していない為に発生しています。
では、キーパッドを閉じるようにしましょう。
- 8. リターンキーでキーパッドを閉じる
リターンキーを押されたことを検知する
UITextFieldDelegate
を使って検知
キーパッドを閉じる
13年3月17日日曜日
リターンキーを押したときにキーパッドを閉じるには図のような処理フローになります。
アプリでリターンキーを押されたことを検知したらキーパッドを閉じるという処理を行うのです。
リターンキーを押されたということを検知するには、UITextFieldDelegateというprotocolを使う必要があります。
- 9. protocolって
オブジェクトの役割や振る舞いを表すメソッド
の集合実装は各オブジェクト内で行う
→Javaでいうインターフェース
iOSのSDKに定義されているprotocolを使うことも
自分で作ることも出来る。
13年3月17日日曜日
protocolというと、ネットワークの世界ではおなじみですが、
Objective-Cの世界では、オブジェクトの役割や振る舞いを表すメソッドの集合のことをさします。
メソッド名および引数のみヘッダファイルに設定しており、実装は各オブジェクト内で行います。
Javaでいうインターフェースと同じだと考えてください。
元々はオブジェクト同士の通信規約のことでしたが、だんだん意味が広くなったようです。
iOSのSDKに定義されているプロトコルを使うことも自分でプロトコルを作ることも出来ます。
- 10. protocolの使用例
同じメソッドでもオブジェクト
によって動作を変える
再生する
DVD Player iPod
13年3月17日日曜日
protocolはどのように使用するのでしょうか。ご存知の方には釈 に説法かと思いますが念のため説明します。
Javaでいうinterfaceのように同じメソッドでもオブジェクトによって処理を変えたい場合に使います。
例えば同じ「再生する」という動作でもDVDプレーヤーで再生する場合とiPodで再生する場合、
機械のなかで行っている処理は異なっている訳です。
ただし、使う側は機械のなかで行っている処理についてはあまり気にしません。
「再生する」という行為を行えば目的を達成できるのです。
- 11. protocolの使用例
他のオブジェクトに通知などの
メッセージを送る
オブジェクトA オブジェクトB
「テキストの中身変わったよ」
「リターンキーおされたよ」
13年3月17日日曜日
先ほどの例を応用し、Objective-Cではこんな使い方をします。
あるオブジェクトから他のオブジェクトに対して通知を行うのです。
例えばオブジェクトAが「自分の持っているテキストの内容が変わった」という内容の通知を行うことが出来るのです。
UITextFieldの場合、「リターンキーが押された」という通知を行うことが出来ます。
- 12. UITextFieldDelegate
UITextField.hを開いてください
@protocolから@end
までに書かれたメソッドが
プロトコルになる
テキスト
プロトコルで設定している
メソッド。実際の処理は実装
側で書く
13年3月17日日曜日
プロトコルが何なのかということがわかった所で、実際に使うものを見ていきましょう。
UITextField.hを開いてください。
Xcodeの左側のウィンドウからFrameworksというディレクトリを開き、UIKit.frameworkを開いてください。そこに
UITextField.hというヘッダがあるのでそれを開きましょう。
ファイルの下の方に@protocolUITextFieldDelegateという記載があると思います。
@protocolと書くとここから@endまでの間に書いているメソッドはプロトコルだということをコンパイラに知らせていま
す。
UITextFieldの場合、テキストの編集が終わった場合の動作やリターンキーを押されたときの動作について、
メソッド名だけ記載しておき、実際の処理は実装側に委譲しているのです。
- 13. ∼ここまでのまとめ∼
•UITextFieldDelegateというprotocolを使う
•リターンキーが押されるとtextFieldShouldReturn
が呼ばれる
•textFieldShouldReturnの実処理は自分で実装する
13年3月17日日曜日
「リターンキーが押された」ことを検知するということについてこれまでのことをまとめておきましょう。
まず、UITextFieldDelegateというプロトコルを使います。
UITextFieldDelegateというプロトコルには”textFieldShoudReturn”というメソッドがあり、
リターンキーを押されたときに呼ばれます。このメソッドは定義だけされているので、
キーパッドを閉じるという処理は委譲先のオブジェクトで行う必要があります。
- 14. 実装方法
■使用するprotocolの設定
UITextFieldを配置したほうの.hファイルに
以下の記述を追加する
@interface クラス名:親クラス <使用するプロトコル>
使用するプロト
@interface SecondViewController : コルを記載
UIViewController<UITextFieldDelegate>
13年3月17日日曜日
では実際の実装方法を解説していきましょう
まず、使用するプロトコルを宣言します。
UITextFieldを配置した方の.hファイルに以下の記述を記載し、このクラスでは”UITextFieldDelegate”を使いますよ。
ということを宣言します。
@interface クラス名 :親クラス <使用するプロトコル>という形式で記載してください。
ここでは@interface SecondViewController : UIViewController<UITextFieldDelegate>
と記載します。
- 15. 実装方法
■メソッドの実処理
UITextFieldを配置したほうの.mファイルに
以下の記述を追加する
#リターンキーを押されたときの処理を実装する
- (BOOL)textFieldShouldReturn:(UITextField*)textField{
//キーパッドを閉じる処理を実行する
[textField resignFirstResponder];
return NO;
} キーパッドを
閉じるメソッド
13年3月17日日曜日
ではメソッドの実処理の実装していきましょう。
UITextFieldを配置した方の.mファイルに
リターンキーが押されたことを検知する「textFieldShouldReturn (UITextField*)texField」メソッドを書きます。
キーパッドを閉じるには「resignFirstResponder」というメソッドを呼びます。
- 16. この状態でコンパイルしてみましょう
キーパッドは閉じたでしょうか???
実はもう一つやることがあるのですが、
何でしょうか???ちょっと考えてみましょう。
13年3月17日日曜日
この状態でコンパイルして実行してみましょう。
キーパッドは閉じたでしょうか・・・。
実はもう一つやらなくてはならないことがあるのですが、何でしょうか。ちょっと考えてみましょう。
- 17. 何が足りないのか?
UITextFieldDelegateを使うことにしたものの、
textFieldShouldReturnメソッドで行う処理を
どこに委譲すればいいかわからない
オブジェクト ???
「リターンキー押したよ」
って誰に処理をしてもらえば
いいんだ???
13年3月17日日曜日
UITextFieldを使うUITextFieldDelegateをつかうということを宣言したのはいいのですが、
textFieldShouldReturnをどこに委譲するかを設定していなかったため、処理が委譲されていなかったのです。
textFieldShouldReturnの呼び出しもととしては、誰が処理を行ってくれるかわからなかったため、
処理をすることが出来なかったのです。
- 18. では、どうすればいいのか??
UITextFieldのdelegate(委譲元)
と委譲先のViewControllerを接続する
13年3月17日日曜日
ではどうすればいいのでしょうか。
処理の委譲先を設定してあげればいいのです。StoryBoardを開いてみましょう。
TextFieldを選択し、コントロールキーを押しながらViewControllerに向けてドラッグします。
そうすると図のように黒い窓が出てくると思います。そこでdelegateを選択してください。
ここで何をしているかというと「textFieldShouldReturn」をViewControllerで行ってもらいますよという設定をしているの
です。
- 19. まとめると・・・
1.UITextFieldDelegateを使うことを宣言
2.textFieldShouldReturnメソッドを実装
3.UITextFieldのdelegateにViewControllerを設定
13年3月17日日曜日
ここまでのことをまとめると、
以下のようになります。
まず、ViewControllerで「UITextFieldDelegateを使いますよ」という宣言をします。
ヘッダファイルの最初に@interface クラス名:親クラス <使用するプロトコル>という形式で記載します。
ViewControllerでtextFieldShouldReturnメソッドを実装します。ここでresignFirstResponderというメソッドを呼び、キ
ーパッドを閉じる処理を行います。
そして、UITextFieldのdelegateにViewControllerを設定します。
StoryBoardの設定を行いましょう。
- 20. TableView
∼このようなViewのことをいいます∼
赤で囲んだ部分:UITableView
青で囲んだ部分:UITableViewCell
UITableViewに
UITableViewCellが含まれている
13年3月17日日曜日
次にTableViewの作り方について学んでいきます。
TableViewの説明をし始めると長くなるので、
残り時間も考えて今日は簡単なTableViewの作り方を学んでいき、次回に続きを行います。
TableViewとはどのようなものかというと、図のように複数行の表示を行うViewのことです。
赤で囲んだ部分をUITableViewといい、テーブル全体のことをさします。
青で囲んだ部分はUITableViewCellといい、1つの行のことをさします。
UITableViewにUITableViewCellが含まれているイメージです。
- 21. StoryBoardを変更
TableViewControllerを
使うので、削除
13年3月17日日曜日
では、簡単なTableViewを作成していきましょう。
新しいプロジェクトを作成してください。プロジェクトを作成したら、デフォルトで作成されるViewControllerを削除しま
す。
ViewController.m、ViewController.hとStoryBoardにあるViewControllerを削除してください。
削除する際は「Move to trash」を選択していただいてかまいません。
- 22. TableViewControllerの作成
UITableViewController
を継承する
13年3月17日日曜日
デフォルトで作成されたViewControllerを削除したら、TableViewControllerを作成しましょう。
ファイルを新しく作成します。
作成するときにUITableViewControllerのサブクラスとして作成してください。
- 23. StoryBoardを変更
作成したクラス名にする
TableViewControllerを
ドラッグして配置する
13年3月17日日曜日
ソースコードを作成したら、StoryBoardを変更します。
StoryBoardを開いて、右部分のTableViewControllerをドラッグします。
ドラッグして配置したら、CustomClassを作成したクラス名にしてください。
- 24. この状態で実行してみましょう
何も無い空っぽのテーブル
が表示される
13年3月17日日曜日
この状態でビルドしてみましょう。エラーは発生していませんが、
何も表示されない空っぽのテーブルが表示されているかと思います。
テーブルの外枠しか設定しておらず、テーブルの中身が無いので当然といえば当然です。
これからは中身を表示できるようにしてみましょう。
- 25. テーブルの中身を表示する
中身を表示するにはどうすればいいのか??
その前に、TableViewの仕組みについて触れて
おきます。
13年3月17日日曜日
さすがに中身の無いTableViewを表示するのも寂しいので、中身を表示させるようにしていきます。
その前に、少しTableViewの仕組みについて触れていきます。
- 26. テーブルの中身を表示する
StoryBoardの編集
TableView
Content:Dynamic:Prototypes
PrototypeCells:1
TableViewCell
Identifier:Cell
Style:Basic
13年3月17日日曜日
まずStoryBoardの設定を行います。
StoryBoardを開き、TableViewを選択してください。
その状態で右のメニューを表示します。右から3番目のマークを選択して、図のような状態になるようにします。
ContentにDynamicPrototypesを選択し、PrototypeCellsに1を設定してください。
ここで何をしているかというと、「このテーブルビューでは行の数を可変にするか固定にするか」ということを設定します。
ここでは「Dynamic:Prototypes」を選択しているので、行の長さを可変とし、ソースコード内で行数を変更することが出来
るようにしています。
PrototypeCellsの設定でテンプレートとなるセルの数を決めています。同じテーブル内でもセルの表示を変更することが出来
ます。ここでは同じテンプレートを使いますので、1にします。
TableViewの下にあるTableViewCellを選択してください。
その状態で右のメニューを開き、図のような設定を行ってください。
IdentifierにCellと設定し、StyleにBasicを設定しましょう。
Identifierとはテーブルのテンプレートを決めるものです。このテンプレートの名前は「Cell」ですということを示していま
す。
- 27. テーブルの中身を表示する
ソースコードの編集
次の3つのメソッドを編集します
- (NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView
指定したTableのsection数
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
指定したSectionの行数
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
指定した箇所のセル
13年3月17日日曜日
次にソースコードの編集を行います。
まず、numberOfSectionsInTableViewというメソッドで、指定されたTableに何個セクションがあるかを呼び出し元に伝え
ます。このメソッドが実装されていない場合は1が返却されます。
tableViewnumberOfRowsInSectionというメソッドで、指定されたSectionに何行あるかを呼び出し元に伝えています。
このメソッドは必ず実装してください。実装しないとエラーになります。
tableViewcellForRowAtIndexPathというメソッドで指定されたIndexPath(セクションと行)のセルを呼び出し元に伝えてい
ます。このメソッドも必ず実装してください。実装しないとエラーになります。
- 28. テーブルの中身を表示する
図解すると・・・
青い線で囲んだ部分
→1つのセクション
黄色い線で囲んだ部分
→セクション1つにある行
赤い線で囲んだ部分
→1つのセル
13年3月17日日曜日
青い線で囲んだ部分が一つのセクションで、
セクション数はnumberOfSectionsInTableViewで指定します。
黄色い線で囲んだ部分がセクション内のすべての行で、指定したセクションの行数はtableViewnumberOfRowsInSectionで
指定します。
赤い線で囲んだ部分が指定したセクションおよび行数に該当する一つのセルで、
tableViewcellForRowAtIndexPathで指定します。
- 29. テーブルの中身を表示する
ソースコードの編集
- (NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView
{
return 1; ここではsection数=1
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return 2;
}
ここでは行数2
13年3月17日日曜日
それではソースコードの編集をしましょう。
まず、 numberOfSectionsInTableViewとnumberOfRowsInSectionを編集します。
セクション1つで2行表示するようにしましょう。
どう指定すればいいでしょうか。。。
- 30. テーブルの中身を表示する
ソースコードの編集
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
if(indexPath.row == 0){
cell.textLabel.text = @"上のセル";
指定したテンプレートから
}
else{ Cellを作成
cell.textLabel.text = @"下のセル";
}
return cell;
} indexPath.rowで何行目かが
わかる
13年3月17日日曜日
それではソースコードの編集をしましょう。
次に、tableView cellForRowAtIndexPathを編集します。
まず、「 dequeueReusableCellWithIdentifier」でテンプレートからCellを作成します。
そして、何行目かによって表示するものを変えます。
indexPath.rowと指定すると、何行目かがわかりますので行数に寄って表示するものを変えましょう。
UITextViewCellにはtextLabelというラベルが標準でありますので、そちらを変更します。
- 32. テーブルの中身を表示する
if文で表示するCellを場合分けしていると
きりがない・・・
NSArrayを使う
→JavaでいうArrayListと同じ使い方をする
13年3月17日日曜日
- 33. NSArrayの使い方
arrayWithObjectsで初期化
NSArray *list = [NSArray arrayWithObjects:@"AAA",@"BBB",nil];
※他にも初期化メソッドはあります
objectAtIndexで指定したIndexのオブジェクトを取得
[list objectAtIndex:0];
※ここでは@”AAA”が返ってくる
countでオブジェクトの数を取得
[list count];
※ここでは2が返ってくる
13年3月17日日曜日
NSArrayの使い方について触れておきます。
まず、初期化メソッドを使って初期化します。arrayWithObjectsを使うと指定したオブジェクトでNSArrayを初期化できま
す。objectAtIndexで指定したIndexのオブジェクトを取得します。countでオブジェクトの数を取得します。
- 34. NSArrayは読み取り専用
編集したいときはNSMutableArrayを使う
addObjectでオブジェクトを追加
[list addObject:@”AAA”; //最後にオブジェクトを追加
insertObjectでオブジェクトを挿入
[list insertObject:@”AAA” atIndex:1]; //1番目にオブジェクトを挿入
removeObjectAtIndexでオブジェクトを削除
[list removeObjectAtIndex:1]; //1番目のオブジェクトを削除
replaceObjectAtIndexでオブジェクトを変更
[list replaceObjectAtIndex:1 withObject:@”BBB”];
//1番目のオブジェクトを@”BBB”に変更
13年3月17日日曜日
ただし、NSArrayは読み取り専用のため、編集が出来ません。
編集したいときはNSMutableArrayを使います。「Mutable」がついているオブジェクトは編集可能ということです。
使い方はJavaのArrayListと似ており、追加、挿入、削除、交換などが出来ます
- 36. 一定時間ごとに処理を行う
NSTimerを使うと一定間隔で同じメソッドを呼び
出すことが出来る
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(increment:)
userInfo:nil
タイマーを初期化して開始す
repeats:YES];
るメソッド
[timer invalidate]; タイマーを止めるメソッド
[timer fire]; タイマーを開始するメソッド
13年3月17日日曜日
第2回目でリクエストがあった、「一定時間ごとに値が更新されるプログラム」について説明をします。NSTimerというクラ
スを使うと、一定時間間隔で同じメソッドを呼び出すことが出来ます。
お渡ししたファイルにNSTimerTestというプロジェクトがありますので、そちらをご覧ください。
- 37. 一定時間ごとに処理を行う
@selectorって何??
→コンパイラに「この引数はメソッドである(SEL
型)」ことを示すもの
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(increment:)
userInfo:nil
repeats:YES];
incrementというメソッドを
渡している
13年3月17日日曜日
ここで@selectorについて少し解説します。
@selectorとはコンパイラに対して「この引数はメソッド(関数)である」ということを教えています。
SEL型と言います。ここで使用しているNSTimerでは自分自身のメソッドを繰り返し呼び出しています。