- ベストアンサー
iPhoneアプリ開発での変数の受け渡しについて
- iPhoneアプリ開発における変数の受け渡しについて質問があります。TableViewCellのIDに入ったデータをprepareForSegueの中のIDに受け渡したいのですが、うまく繋がりません。ご教授お願いします。
- iPhoneアプリ開発で変数を受け渡す方法について質問です。TableViewCell内のIDに入ったデータをprepareForSegueの中のIDに受け渡したいのですが、うまくいきません。初歩的な質問ですが、ご教授いただけますか。
- iPhoneアプリ開発初心者です。TableViewCellのIDに入ったデータをprepareForSegueの中のIDに受け渡したいのですが、うまくいきません。どのようにすれば正しく繋がるのか、ご教授ください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> Receiver (<NewDemoTableViewController: 0x8c61820>) has no segue with identifier 'mySegue' このエラーメッセージの意味はわかりますか? 英語メッセージの意味を理解しようとしていますか? 暗号じゃないです。あなたに伝えたい重要なメッセージが入っているのです。 上記のメッセージには 「レシーバー(NewDemoTableViewController)には'mySegue'という識別子を持つセグエがありません。」 と書いています。 NewDemoTableViewControllerからSecondNewDemoTableViewControllerにSegueの線を引いていますか? また、そのSegueの線に「mySegue」という名前をつけていますか? 今回の変数受け渡しの質問以前の基本的な問題です。 まずは普通に画面遷移するところから再確認してください。
その他の回答 (5)
- Lchan0211b
- ベストアンサー率61% (573/930)
Outputウインドウに何かエラーメッセージが出ていると思うのですが、 それを書いてください。 それと、 http://www.zero4racer.com/blog/480 の対策1を参考にしてException Break Pointを設定してから 実行してみてください。 これを設定しておけば、例外が発生した時点で止まるので 原因を見つけやすいと思います。 今はException Break Pointが設定されてないので、 その例外を処理できるところまで戻ろうとし、 結局その処理できる人がいなかったので、 これ以上戻れないmain関数まで戻ったところで 例外表示となっているのです。 ちなみにSecondNewDemoTableViewControllerのmyValueプロパティは 文字列をいれるならNSString型、選択行番号を入れるなら整数型 にしていますよね?
お礼
詳しくありがとうございます。 エラーメッセージというのは、以下の箇所になりますでしょうか。 DemoTest0331[29013:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<NewDemoTableViewController: 0x8c61820>) has no segue with identifier 'mySegue'' はい、今回は文字列を入れているので、myValueはNSString型にしています。 教えていただいた方法でBreak Pointを設定してみたところ、(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath内の[self performSegueWithIdentifier:@"mySegue" sender:self];の箇所でエラーが出ているようでした。
- Lchan0211b
- ベストアンサー率61% (573/930)
ぱっと見でおかしそうなところはわかりませんでした。 ほぼ同じコードで動作することは、こちらでも確認済みです。 「うまく動作しない」というのが、どううまく動作しないのか (どこでどのようなメッセージが出て、画面がどのような状況なのか。 特に正確なメッセージ内容)を説明してください。
お礼
状況としては今までと同じく、ビルドは成功してアプリは起動する(1枚目の画面は出てくる)のですが、セルをタップするとそこで動作が止まってXcodeでエラーが出される、といった感じです。 エラーは、Supporting Files内のmain.mの以下の箇所にThread 1:signal SIGABRTが出ています。 int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([NewDemoAppDelegate class])); ←ここです } }
- Lchan0211b
- ベストアンサー率61% (573/930)
No.1,2です。 > またprepareForSegueの中身は以下のようなコードで合っていますでしょうか。 > ビルドはできるものの、1枚目でセルをタップした時点でエラーが出てしまう状態です。 あぁ、すみません。うっかりしていました。 今回のケースは、didSelectRowAtIndexPathの中の [self performSegueWithIdentifier:@"mySegue" sender:self]; でSegueを起動していますから、prepareForSegueのsenderで受け取る オブジェクトは、そのperformSegueWithIdentifierのsenderに指定した オブジェクトになります。つまり今のコーディングではself(=UITableViewController) が渡されます。prepareForSegueのsenderでセルを受け取れるようにするには、 didSelectRowAtIndexPathを以下のようにする必要があります。 --------------------------------------------------------- -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; [self performSegueWithIdentifier:@"mySegue" sender:cell]; } --------------------------------------------------------- ただ、それならdidSelectRowAtIndexPathは、今のままにして、 prepareForSegueの方を以下のようにしてもよいと思います。 --------------------------------------------------------- -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"mySegue"]) { ViewController *viewCon = segue.destinationViewController; NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; viewCon.myValue = cell.textLabel.text; } } --------------------------------------------------------- また、選択セルの文字列を渡すのではなくて選択行番号を渡したいのなら、 --------------------------------------------------------- NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; viewCon.myValue = indexPath.row; --------------------------------------------------------- とすればよいです。
お礼
また、詳しくありがとうございます。 教えていただいた方法を試してみたのですが、どちらでもアプリがうまく動作してくれませんでした・・・。 prepareForSegueの中身を書き換える方のやり方でやってみたコードが以下のようになるのですが、どこか不適切な箇所がありますでしょうか。 丸投げしてしまい申し訳ありませんが、よろしくお願いします。 1枚目の画面がNewDemoTableViewcontroller、2枚目がSecondNewDemoTableViewcontrollerとしています。 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self performSegueWithIdentifier:@"mySegue" sender:self]; } -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"mySegue"]) { SecondNewDemoTableViewController *viewCon = segue.destinationViewController; NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; viewCon.myValue = cell.textLabel.text; } }
- Lchan0211b
- ベストアンサー率61% (573/930)
No.1です。 No.1の回答は、タップしたセルに対応した値(「東京」とか「大阪」とか)を 呼び出し先のビューコントローラーに伝えるにはどうしたらいいか という質問だと思って回答しました。 が、質問をもう一度よく読んでみると > - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 以下で設定したIDに入ったデータを、 > -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderの中のIDに受け渡したい と書いてあり、IDの設定個所は int ID = indexPath.row; となっています。 しかし、この文は表示処理しているセルの行番号(indexPath.row)を ローカル変数のIDに設定しているだけで、このままでは無意味だし、 もともと何がしたかったのかもわかりません。 元々私が想定したように、「東京」とか「大阪」とか、タップしたセルの内容を伝えたかったのなら、 int ID = indexPath.row; は不要で、 prepareForSegueの中で UITableViewCell *cell = (UITableViewCell *)sender; viewCon.myValue = cell.textLabel.text とすればいいだけです。 やりたいことが違うなら、補足してください。
お礼
参考も含め、詳しくありがとうございます。大変勉強になりました。 またどういったことがしたいかも書かずに質問してしまい、失礼いたしました。 やりたい内容は、1番目の画面でどのセルがタップされたかという情報を2枚目に渡し、その情報に応じて2枚目に表示する内容を選択する、といったものです。 ですので渡す情報としては行インデックスでもセルのテキストでもいかなと思っています。 テキストを渡す方法を取るとすると、Lchan0211b様がNo.2の最後で示してくださったコードでいいのだと思うのですが、その場合2枚目でmyValueと結びつけられている_myValueにセルのテキストデータが入る、ということでよいのでしょうか。 またprepareForSegueの中身は以下のようなコードで合っていますでしょうか。 ビルドはできるものの、1枚目でセルをタップした時点でエラーが出てしまう状態です。 質問ばかりで申し訳ありませんが、どうかよろしくお願いいたします。 -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"mySegue"]) { SecondTableViewController *viewCon = segue.destinationViewController; UITableViewCell *cell = (UITableViewCell *)sender; viewCon.myValue = cell.textLabel.text; } }
- Lchan0211b
- ベストアンサー率61% (573/930)
http://d.hatena.ne.jp/appbakery/20130113/p1 が参考になると思います。 prepareForSegueの中でindexPathForSelectedRowを使って タップされたテーブルの行インデックスを得てもいいし、 senderには、タップされたセルのオブジェクトが入っているので そこから情報を得ることも可能です。
お礼
1つ前のお礼をした後にSegueを引き忘れていることに気づき、補足にその旨を書いたつもりだったのですが反映されていないようでした 。。。 確認しておらず申し訳ありませんでした。 Segueをきちんと引くと今まで出ていたエラーは消えたのですが、今度はUnknown class Cell in Interface Builder file.というエラーが出てしまいました。 同様のエラーメッセージが出ている例を探してみると、どうやら他のプロジェクトからクラスをコピーペーストした際にそのクラスがビルド対象に入っておらず出てしまうメッセージのようでした。ただ今回はすべてのクラスがきちんとビルド対象に入っており、なぜこのエラーが吐き出されているのかわかりません。。 Exception Break Pointにも引っかかりませんでした。 CellというのはTableView Cellに付けたIdentifierのことだと思うのですが・・・。
補足
質問投稿者です。重ねてすいません。 先ほど、新しく同様のプロジェクトを作ってみたところ無事に動いてくれました。 結局エラーの原因はわからずじまいでしたが・・・とにかく、これで前に進むことができそうです。 Lchan0211b様には大変お世話になりまして、本当にありがとうございました。 また、自分の無知から色々とご迷惑をおかけしてしまい申し訳ありませんでした。 また、お世話になることがありましたらその時はどうぞよろしくお願いいたします。