For Want Of A Better Word

【iOS_Xcode5】 Mastere-Detailテンプレートの要素追加の処理を追う

      2015/04/18

テンプレートを作った時デフォルトで「+」を押した時に時刻の行が追加されて、詳細に行くと時刻が表示される。。

Detailで時刻をどうやって表示しているのか、っていう所が気になったのが発端。
なのでDetailの文字列設定部分から。

まず、DetailViewに文字を設定している部分は下記

self.detailDescriptionLabelが時刻を表示しているラベルにあたる。
そのtextプロパティに値を文言をセットすると、表示が変わると。

じゃあこのdetailDescriptionLabelってどんなプロパティを持っているのかを知りたい。。
そのためには型(クラス)が分かればリファレンスも見られるはず。

定義はhファイルにあるのでー見てみる…

これは、、、ちょっと意味を整理。

  • weak -Outletの指定。
  • nonatomicは非スレッドセーフ
    • スレッドセーフの意味は下記

マルチスレッドプログラミングにおける概念である。あるコードがスレッドセーフであるという場合、
そのコードを複数のスレッドが同時並行的に実行しても問題が発生しないことを意味する。

(by wikipedia)

  • (メモ)IBOutletやIBActionはなんだ!

ドラッグ&ドロップの接続によってIBoutletやIBActionというキーワードがコード中に自動生成される。
InterfaceBUiler(Xcode5)が接続コードを識別するためのもので、Objective-C的には意味が無いらしい。。
(参考:作ればわかるiOS7)
さらに

  • IBOutletとは、パーツ自体をプログラムで定義した変数に紐付けるもの
  • IBActionとは、パーツに何か変化を加えたときの動作をプログラムへ引き渡すものです。

そうすると…IBAOUtletを無視すると、先の@property宣言はUILabel型の宣言に当たるので、
下記とか見ればOKと。

ふむ、まずまず。

んでだ、クリック時にtextプロパティを書き換えているとういことがわかった。
しかしだよ。たとえばテキストを設定したとすると、全ての詳細ページでそのテキストが表示されることになる。
今は時刻が表示されているけど、[self.detailItem description]がその時刻(おそらくリストに表示されているものと同じ)

じゃあ、これがなんなのかってのが、問題なんだけど

self.detailItem= DetailViewController.detailItem

descriptionを呼び出して―と。

これらはどこに定義されているのか?
ストーリーボードで階層を追ってもDetailViewControllerにdetailItemという設定値は無い。
ソースを見ると、

と定義されている。んでDetailViewController.mでdetailItemが登場してくるのは下記。

むむむ、ここで「configureView」が呼ばれている。。
繋がってきたぞ。
こいつの引数がdetailItemにセットされて、configureViewを実行し書き換えて表示。。。
(※という事はDetailViewってリスト分あるんじゃなくて、リスト毎に表示を変更しているだけという事か。)

ということは、setDetailItemがMasterViewからよびだされて、タイトルを一緒に渡していそう。

ということでMasterViewControllerをsetDetailItemで検索すると、

出てきたぜ、ヌルリと。
①prepareForSegue()は segueでの遷移前に実行されるメソッド
②segue のidentifierを取得して”showDetail”だったら★1
③セレクトされた行のインデックスパスを取得して 、
④_objects[行]で格納されている、NSDate型のものを取って、★2
⑤[segue destinationViewController]で到達先のインスタンスを取得して、さらに setDetailItem:objectとして呼び出している。

ふむふむ、こうやって連携していたのか。

※delegateってわけじゃないのかなこれは..相手のメソッド呼び出して渡しているだけだし。。この値の渡しかたとdelegateでの渡し方は、何が違うんだろ。。

★1(補足)segueのidentifierの定義はストーリーボード>該当のセグエを選択、プロパティの所から確認可能。新たに設定するときは自分でここを書く!

★2(補足)_objectsについて
こいつはMasterViewController.mで設定されている

@interfaceで宣言して…
なんで.hじゃないんだろと思ったら

内部で使うインスタンス変数はなるべく.m側に書くようにする。IBOutlet, IBAction も .h に書く必要は無い。

(参考:http://qiita.com/CarmineScarlet/items/d1db307ee31ac83ae38f)

なるほどね。閑話休題

insertNewObjectの中で、

  • ①[NSDate date]を index0に insertしている。
  • ②NSIndexPath(0,0の位置)オブジェクトを取得して、
  • ③tableViewにInsertRowsAtIndexPath….ここがちよっとよく分からない。テーブルの描画という事だろうけど、_objectsを入れている様子もないし。。

ここを消すとテーブルにObjectが追加されない。

フム、ここまで来たらもうちょっとさかのぼる!

じゃあ「insertNewObject()」を呼び出しているのはどこだっつーと、

①で(UIBarButtonItem)addButtonのインスタンスを作成して関数insertNewObjectを関連付け「action:@selector(insertNewObject:)」
※「UIBarButtonSystemItemAdd」は初期化時にボタンの種類を伝えている。

②で、「self.navigationItem.rightBarButtonItem」にボタンをセット!

viewDidLoadについてはViewControllerのライフサイクルという事で下記参照

iPhone開発 UIViewController ライフサイクル viewDidLoad viewWillAppear viewDidAppear viewWillDisappear viewDidDisappear ios 逆引き サンプル | Linux & iOS & Android Labs

参考になりやす。

ふー…
いままでの流れを逆にすると、「+」ボタンの作り方分かるはず。

  • ①ボタンを設置したいViewのDidLoadメソッドで
    • ボタンの作成。この時実施したいメソッドを、action:@selector(…)として記述。メソッドの実装は後でも先でも
    • ナビバーインスタンスにセット。

※ ここではコードでやっているけど、GUIでもなんかできそうな予感。

  • ②メソッドの実装
    • 先に記述した呼び出したいメソッドを書く!(ボタンを置いているControllerクラスでよい。)
  • ③詳細画面に遷移したときに実施したいメソッドを詳細画面側に記述。
  • ④詳細画面へのセグエにidentiferをつける。
  • ⑤遷移元の「prepareForSegue」で、④のidentifierだったら、「[segue destinationViewController]」の③のメソッドを実行するようメッセージを記述。

大体こんな感じ?

 - ios, objective-c, xcode

  関連記事

objective-c
iOS7+Xcode5開発_メモ帳サンプルアプリ改修①編集終了後キーボードを隠す。

編集終了後キーボードを隠す。 TextFieldについて [参考]http:// …

objective-c
【Objective-C】ファイル構成-実行の流れ

参考:http://yksmtmks.blogspot.com/2011/02/ …

objective-c
【iOS7+Xcode5】FMDBサンプルアプリの構造確認①

DBの使い方を確認して、最終的には下記サイトを参考に作ったメモアプリを修正する形 …

objective-c
【iOS+Xcode5】[DetailViewController titleField:]: unrecognized selector sent to instance

タイトルはハマったエラー。 下記のメモアプリを作っていたら発生。。 iPhone …

objective-c
【iOS7+Xcode5】FMDB+todoアプリの

前回動かすことはできたので 下記のサンプルアプリのソースを見て、どんな風に定義し …