i phoneアプリ入門 第4回

38
第4回 iPhone勉強会 13317日日曜日

Upload: sachiko-kajishima

Post on 28-Jul-2015

594 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: I phoneアプリ入門 第4回

第4回 iPhone勉強会

13年3月17日日曜日

Page 2: I phoneアプリ入門 第4回

・第5回 TableView続き・第6回 ユーザ操作(タップなど)の検出方法

現在地の取得方法・第7回 MapKitを使った地図の表示方法

ブラウザでGoogleMapを表示する

今後の予定

13年3月17日日曜日

Page 3: I phoneアプリ入門 第4回

・前回の復習・protocolとdelegate・テーブルビュー・タイマー(一定時間ごとに処理を実行)・サンプルアプリ作成

今日のアジェンダ

13年3月17日日曜日

今日のスケジュールは以下の通りです。まず、前回の復習を軽く行った後、キーパッドの閉じかたとデリゲートについて勉強します。その後、テーブルビューについて勉強します。タイマーについては時間があったら行う予定です。今日も手を動かしていきましょう。よろしくおねがいします。

Page 4: I phoneアプリ入門 第4回

~以下のようなアプリを作ってみましょう~

前回の復習

押すと次の画面へ移動する

動かすと文字色が変わる

13年3月17日日曜日

まず、前回の復習をしましょう。前回受講したという前提で、まずはコードを書いてみます。図のようなアプリを作ってみましょう。iPhone上でボタンを押したら次の画面が表示される次の画面ではRGBをスライダーで設定し、設定した値が最初の画面に反映される・前回やったシングルトンを使います。何のことだかさっぱりわからないと言う方、こっそり教えてください・・・。

Page 5: I phoneアプリ入門 第4回

前回勉強したこと

• 強い参照と弱い参照→循環参照が発生するものには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でもよく出てくるデザインパターンで、オブジェクトを一つだけ持つものです。どこからでもアクセスしたいオブジェクトに対して適用します。

Page 6: I phoneアプリ入門 第4回

~機能を追加しましょう~

protocolとdelegate

13年3月17日日曜日

では、ここで復習で作ったアプリに機能を1つ追加しましょう。色の変更だけでなく、表示する文字列を変更するようにしてみましょう。2番目に表示される画面で文字入力を行ってその結果を最初の画面に反映するようにしましょう。2番目の画面ではテキストフィールドというものを使いましょう。

Page 7: I phoneアプリ入門 第4回

キーパッドを閉じるには

キーパッドが閉じないのは不便・・・

13年3月17日日曜日

使ってみて、不便に思ったことは無いでしょうか。「キーパッドが閉じてくれない」「入力してもすぐに反映してくれない」この2つはキーパッドを閉じるという機能を実装していない為に発生しています。では、キーパッドを閉じるようにしましょう。

Page 8: I phoneアプリ入門 第4回

リターンキーでキーパッドを閉じる

リターンキーを押されたことを検知する

キーパッドを閉じる

UITextFieldDelegateを使って検知

13年3月17日日曜日

リターンキーを押したときにキーパッドを閉じるには図のような処理フローになります。アプリでリターンキーを押されたことを検知したらキーパッドを閉じるという処理を行うのです。リターンキーを押されたということを検知するには、UITextFieldDelegateというprotocolを使う必要があります。

Page 9: I phoneアプリ入門 第4回

protocolって

オブジェクトの役割や振る舞いを表すメソッドの集合実装は各オブジェクト内で行う →Javaでいうインターフェース

iOSのSDKに定義されているprotocolを使うことも自分で作ることも出来る。

13年3月17日日曜日

protocolというと、ネットワークの世界ではおなじみですが、Objective-Cの世界では、オブジェクトの役割や振る舞いを表すメソッドの集合のことをさします。メソッド名および引数のみヘッダファイルに設定しており、実装は各オブジェクト内で行います。

Javaでいうインターフェースと同じだと考えてください。元々はオブジェクト同士の通信規約のことでしたが、だんだん意味が広くなったようです。

iOSのSDKに定義されているプロトコルを使うことも自分でプロトコルを作ることも出来ます。

Page 10: I phoneアプリ入門 第4回

protocolの使用例

DVD Player iPod

同じメソッドでもオブジェクトによって動作を変える

再生する

13年3月17日日曜日

protocolはどのように使用するのでしょうか。ご存知の方には釈迦に説法かと思いますが念のため説明します。Javaでいうinterfaceのように同じメソッドでもオブジェクトによって処理を変えたい場合に使います。例えば同じ「再生する」という動作でもDVDプレーヤーで再生する場合とiPodで再生する場合、機械のなかで行っている処理は異なっている訳です。ただし、使う側は機械のなかで行っている処理についてはあまり気にしません。「再生する」という行為を行えば目的を達成できるのです。

Page 11: I phoneアプリ入門 第4回

protocolの使用例

オブジェクトA オブジェクトB

他のオブジェクトに通知などのメッセージを送る

「テキストの中身変わったよ」

「リターンキーおされたよ」

13年3月17日日曜日

先ほどの例を応用し、Objective-Cではこんな使い方をします。あるオブジェクトから他のオブジェクトに対して通知を行うのです。例えばオブジェクトAが「自分の持っているテキストの内容が変わった」という内容の通知を行うことが出来るのです。UITextFieldの場合、「リターンキーが押された」という通知を行うことが出来ます。

Page 12: I phoneアプリ入門 第4回

UITextFieldDelegate

UITextField.hを開いてください

テキスト

@protocolから@endまでに書かれたメソッドがプロトコルになる

プロトコルで設定しているメソッド。実際の処理は実装

側で書く

13年3月17日日曜日

プロトコルが何なのかということがわかった所で、実際に使うものを見ていきましょう。UITextField.hを開いてください。Xcodeの左側のウィンドウからFrameworksというディレクトリを開き、UIKit.frameworkを開いてください。そこにUITextField.hというヘッダがあるのでそれを開きましょう。

ファイルの下の方に@protocolUITextFieldDelegateという記載があると思います。@protocolと書くとここから@endまでの間に書いているメソッドはプロトコルだということをコンパイラに知らせています。UITextFieldの場合、テキストの編集が終わった場合の動作やリターンキーを押されたときの動作について、メソッド名だけ記載しておき、実際の処理は実装側に委譲しているのです。

Page 13: I phoneアプリ入門 第4回

~ここまでのまとめ~

•UITextFieldDelegateというprotocolを使う

•リターンキーが押されるとtextFieldShouldReturnが呼ばれる

•textFieldShouldReturnの実処理は自分で実装する

13年3月17日日曜日

「リターンキーが押された」ことを検知するということについてこれまでのことをまとめておきましょう。

まず、UITextFieldDelegateというプロトコルを使います。UITextFieldDelegateというプロトコルには”textFieldShoudReturn”というメソッドがあり、リターンキーを押されたときに呼ばれます。このメソッドは定義だけされているので、キーパッドを閉じるという処理は委譲先のオブジェクトで行う必要があります。

Page 14: I phoneアプリ入門 第4回

実装方法

■使用するprotocolの設定

@interface SecondViewController : UIViewController<UITextFieldDelegate>

使用するプロトコルを記載

@interface クラス名:親クラス <使用するプロトコル>

UITextFieldを配置したほうの.hファイルに以下の記述を追加する

13年3月17日日曜日

では実際の実装方法を解説していきましょう

まず、使用するプロトコルを宣言します。UITextFieldを配置した方の.hファイルに以下の記述を記載し、このクラスでは”UITextFieldDelegate”を使いますよ。ということを宣言します。

@interface クラス名 :親クラス <使用するプロトコル>という形式で記載してください。ここでは@interface SecondViewController : UIViewController<UITextFieldDelegate>と記載します。

Page 15: I phoneアプリ入門 第4回

実装方法

■メソッドの実処理

#リターンキーを押されたときの処理を実装する- (BOOL)textFieldShouldReturn:(UITextField*)textField{ //キーパッドを閉じる処理を実行する [textField resignFirstResponder]; return NO;

} キーパッドを閉じるメソッド

UITextFieldを配置したほうの.mファイルに以下の記述を追加する

13年3月17日日曜日

ではメソッドの実処理の実装していきましょう。UITextFieldを配置した方の.mファイルにリターンキーが押されたことを検知する「textFieldShouldReturn (UITextField*)texField」メソッドを書きます。キーパッドを閉じるには「resignFirstResponder」というメソッドを呼びます。

Page 16: I phoneアプリ入門 第4回

この状態でコンパイルしてみましょう

キーパッドは閉じたでしょうか???

実はもう一つやることがあるのですが、何でしょうか???ちょっと考えてみましょう。

13年3月17日日曜日

この状態でコンパイルして実行してみましょう。キーパッドは閉じたでしょうか・・・。

実はもう一つやらなくてはならないことがあるのですが、何でしょうか。ちょっと考えてみましょう。

Page 17: I phoneアプリ入門 第4回

何が足りないのか?

UITextFieldDelegateを使うことにしたものの、textFieldShouldReturnメソッドで行う処理をどこに委譲すればいいかわからない

オブジェクト

「リターンキー押したよ」って誰に処理をしてもらえばいいんだ???

???

13年3月17日日曜日

UITextFieldを使うUITextFieldDelegateをつかうということを宣言したのはいいのですが、textFieldShouldReturnをどこに委譲するかを設定していなかったため、処理が委譲されていなかったのです。textFieldShouldReturnの呼び出しもととしては、誰が処理を行ってくれるかわからなかったため、処理をすることが出来なかったのです。

Page 18: I phoneアプリ入門 第4回

では、どうすればいいのか??

 UITextFieldのdelegate(委譲元)と委譲先のViewControllerを接続する

13年3月17日日曜日

ではどうすればいいのでしょうか。処理の委譲先を設定してあげればいいのです。StoryBoardを開いてみましょう。TextFieldを選択し、コントロールキーを押しながらViewControllerに向けてドラッグします。そうすると図のように黒い窓が出てくると思います。そこでdelegateを選択してください。

ここで何をしているかというと「textFieldShouldReturn」をViewControllerで行ってもらいますよという設定をしているのです。

Page 19: I phoneアプリ入門 第4回

まとめると・・・

1.UITextFieldDelegateを使うことを宣言

2.textFieldShouldReturnメソッドを実装

3.UITextFieldのdelegateにViewControllerを設定

13年3月17日日曜日

ここまでのことをまとめると、以下のようになります。まず、ViewControllerで「UITextFieldDelegateを使いますよ」という宣言をします。ヘッダファイルの最初に@interface クラス名:親クラス <使用するプロトコル>という形式で記載します。ViewControllerでtextFieldShouldReturnメソッドを実装します。ここでresignFirstResponderというメソッドを呼び、キーパッドを閉じる処理を行います。そして、UITextFieldのdelegateにViewControllerを設定します。StoryBoardの設定を行いましょう。

Page 20: I phoneアプリ入門 第4回

~このようなViewのことをいいます~

TableView

赤で囲んだ部分:UITableView青で囲んだ部分:UITableViewCell

UITableViewにUITableViewCellが含まれている

13年3月17日日曜日

次にTableViewの作り方について学んでいきます。TableViewの説明をし始めると長くなるので、残り時間も考えて今日は簡単なTableViewの作り方を学んでいき、次回に続きを行います。

TableViewとはどのようなものかというと、図のように複数行の表示を行うViewのことです。       赤で囲んだ部分をUITableViewといい、テーブル全体のことをさします。青で囲んだ部分はUITableViewCellといい、1つの行のことをさします。UITableViewにUITableViewCellが含まれているイメージです。

Page 21: I phoneアプリ入門 第4回

StoryBoardを変更

TableViewControllerを使うので、削除

13年3月17日日曜日

では、簡単なTableViewを作成していきましょう。新しいプロジェクトを作成してください。プロジェクトを作成したら、デフォルトで作成されるViewControllerを削除します。ViewController.m、ViewController.hとStoryBoardにあるViewControllerを削除してください。削除する際は「Move to trash」を選択していただいてかまいません。

Page 22: I phoneアプリ入門 第4回

TableViewControllerの作成

UITableViewControllerを継承する

13年3月17日日曜日

デフォルトで作成されたViewControllerを削除したら、TableViewControllerを作成しましょう。ファイルを新しく作成します。作成するときにUITableViewControllerのサブクラスとして作成してください。

Page 23: I phoneアプリ入門 第4回

StoryBoardを変更

TableViewControllerをドラッグして配置する

作成したクラス名にする

13年3月17日日曜日

ソースコードを作成したら、StoryBoardを変更します。StoryBoardを開いて、右部分のTableViewControllerをドラッグします。ドラッグして配置したら、CustomClassを作成したクラス名にしてください。

Page 24: I phoneアプリ入門 第4回

この状態で実行してみましょう

何も無い空っぽのテーブルが表示される

13年3月17日日曜日

この状態でビルドしてみましょう。エラーは発生していませんが、何も表示されない空っぽのテーブルが表示されているかと思います。テーブルの外枠しか設定しておらず、テーブルの中身が無いので当然といえば当然です。

これからは中身を表示できるようにしてみましょう。

Page 25: I phoneアプリ入門 第4回

テーブルの中身を表示する

中身を表示するにはどうすればいいのか??

その前に、TableViewの仕組みについて触れておきます。

13年3月17日日曜日

さすがに中身の無いTableViewを表示するのも寂しいので、中身を表示させるようにしていきます。その前に、少しTableViewの仕組みについて触れていきます。

Page 26: I phoneアプリ入門 第4回

テーブルの中身を表示するStoryBoardの編集

TableViewCellIdentifier:CellStyle:Basic

TableViewContent:Dynamic:Prototypes

PrototypeCells:1

13年3月17日日曜日

まずStoryBoardの設定を行います。StoryBoardを開き、TableViewを選択してください。その状態で右のメニューを表示します。右から3番目のマークを選択して、図のような状態になるようにします。ContentにDynamicPrototypesを選択し、PrototypeCellsに1を設定してください。ここで何をしているかというと、「このテーブルビューでは行の数を可変にするか固定にするか」ということを設定します。ここでは「Dynamic:Prototypes」を選択しているので、行の長さを可変とし、ソースコード内で行数を変更することが出来るようにしています。PrototypeCellsの設定でテンプレートとなるセルの数を決めています。同じテーブル内でもセルの表示を変更することが出来ます。ここでは同じテンプレートを使いますので、1にします。TableViewの下にあるTableViewCellを選択してください。その状態で右のメニューを開き、図のような設定を行ってください。IdentifierにCellと設定し、StyleにBasicを設定しましょう。Identifierとはテーブルのテンプレートを決めるものです。このテンプレートの名前は「Cell」ですということを示しています。

Page 27: I phoneアプリ入門 第4回

テーブルの中身を表示する

ソースコードの編集次の3つのメソッドを編集します

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

指定したTableのsection数

指定したSectionの行数

指定した箇所のセル13年3月17日日曜日

次にソースコードの編集を行います。まず、numberOfSectionsInTableViewというメソッドで、指定されたTableに何個セクションがあるかを呼び出し元に伝えます。このメソッドが実装されていない場合は1が返却されます。tableViewnumberOfRowsInSectionというメソッドで、指定されたSectionに何行あるかを呼び出し元に伝えています。このメソッドは必ず実装してください。実装しないとエラーになります。tableViewcellForRowAtIndexPathというメソッドで指定されたIndexPath(セクションと行)のセルを呼び出し元に伝えています。このメソッドも必ず実装してください。実装しないとエラーになります。

Page 28: I phoneアプリ入門 第4回

テーブルの中身を表示する

図解すると・・・

青い線で囲んだ部分→1つのセクション

黄色い線で囲んだ部分→セクション1つにある行

赤い線で囲んだ部分→1つのセル

13年3月17日日曜日

青い線で囲んだ部分が一つのセクションで、セクション数はnumberOfSectionsInTableViewで指定します。黄色い線で囲んだ部分がセクション内のすべての行で、指定したセクションの行数はtableViewnumberOfRowsInSectionで指定します。赤い線で囲んだ部分が指定したセクションおよび行数に該当する一つのセルで、tableViewcellForRowAtIndexPathで指定します。

Page 29: I phoneアプリ入門 第4回

テーブルの中身を表示する

ソースコードの編集- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1;}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 2;}

ここではsection数=1

ここでは行数2

13年3月17日日曜日

それではソースコードの編集をしましょう。まず、 numberOfSectionsInTableViewとnumberOfRowsInSectionを編集します。セクション1つで2行表示するようにしましょう。どう指定すればいいでしょうか。。。

Page 30: I phoneアプリ入門 第4回

テーブルの中身を表示する

ソースコードの編集- (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.textLabel.text = @"下のセル"; } return cell;}

指定したテンプレートからCellを作成

indexPath.rowで何行目かがわかる

13年3月17日日曜日

それではソースコードの編集をしましょう。次に、tableView cellForRowAtIndexPathを編集します。まず、「 dequeueReusableCellWithIdentifier」でテンプレートからCellを作成します。そして、何行目かによって表示するものを変えます。indexPath.rowと指定すると、何行目かがわかりますので行数に寄って表示するものを変えましょう。UITextViewCellにはtextLabelというラベルが標準でありますので、そちらを変更します。

Page 31: I phoneアプリ入門 第4回

テーブルの中身を表示する

この状態でコンパイルしてみましょう

このような表示になりましたか??

13年3月17日日曜日

この状態でコンパイルしてみましょう。うまく表示されましたでしょうか?

Page 32: I phoneアプリ入門 第4回

テーブルの中身を表示する

if文で表示するCellを場合分けしているときりがない・・・

NSArrayを使う→JavaでいうArrayListと同じ使い方をする

13年3月17日日曜日

Page 33: I phoneアプリ入門 第4回

NSArrayの使い方

NSArray *list = [NSArray arrayWithObjects:@"AAA",@"BBB",nil];

※他にも初期化メソッドはあります

[list objectAtIndex:0]; ※ここでは@”AAA”が返ってくる

arrayWithObjectsで初期化

objectAtIndexで指定したIndexのオブジェクトを取得

countでオブジェクトの数を取得[list count]; ※ここでは2が返ってくる

13年3月17日日曜日

NSArrayの使い方について触れておきます。まず、初期化メソッドを使って初期化します。arrayWithObjectsを使うと指定したオブジェクトでNSArrayを初期化できます。objectAtIndexで指定したIndexのオブジェクトを取得します。countでオブジェクトの数を取得します。

Page 34: I phoneアプリ入門 第4回

NSArrayは読み取り専用

編集したいときはNSMutableArrayを使う

addObjectでオブジェクトを追加

insertObjectでオブジェクトを挿入

removeObjectAtIndexでオブジェクトを削除

replaceObjectAtIndexでオブジェクトを変更

[list addObject:@”AAA”; //最後にオブジェクトを追加

[list insertObject:@”AAA” atIndex:1]; //1番目にオブジェクトを挿入

[list removeObjectAtIndex:1]; //1番目のオブジェクトを削除

[list replaceObjectAtIndex:1 withObject:@”BBB”]; //1番目のオブジェクトを@”BBB”に変更

13年3月17日日曜日

ただし、NSArrayは読み取り専用のため、編集が出来ません。編集したいときはNSMutableArrayを使います。「Mutable」がついているオブジェクトは編集可能ということです。使い方はJavaのArrayListと似ており、追加、挿入、削除、交換などが出来ます

Page 35: I phoneアプリ入門 第4回

では、NSArrayを使ってセルの中身を変更してみましょう

13年3月17日日曜日

Page 36: I phoneアプリ入門 第4回

一定時間ごとに処理を行う

NSTimerを使うと一定間隔で同じメソッドを呼び出すことが出来る

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(increment:) userInfo:nil repeats:YES];

[timer invalidate];

[timer fire];

タイマーを初期化して開始するメソッド

タイマーを止めるメソッド

タイマーを開始するメソッド

13年3月17日日曜日

第2回目でリクエストがあった、「一定時間ごとに値が更新されるプログラム」について説明をします。NSTimerというクラスを使うと、一定時間間隔で同じメソッドを呼び出すことが出来ます。 お渡ししたファイルにNSTimerTestというプロジェクトがありますので、そちらをご覧ください。

Page 37: I phoneアプリ入門 第4回

一定時間ごとに処理を行う

@selectorって何??→コンパイラに「この引数はメソッドである(SEL型)」ことを示すもの

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(increment:) userInfo:nil repeats:YES];

incrementというメソッドを渡している

13年3月17日日曜日

ここで@selectorについて少し解説します。@selectorとはコンパイラに対して「この引数はメソッド(関数)である」ということを教えています。SEL型と言います。ここで使用しているNSTimerでは自分自身のメソッドを繰り返し呼び出しています。

Page 38: I phoneアプリ入門 第4回

ご清聴ありがとうございました

13年3月17日日曜日