続きます。
前回、新規の+ボタンでDetail画面に行って保存で戻ってくる所まで出来ました。
次はすでにあるセルをタップして編集に行きます。
Master-Detail ApplicationではセルをタップするとDetail画面にセグエする仕様になっています。
このセグエにはshowDetailというidentifierが付いています。
セグエで移動する前に呼ばれるのはprepareForSegueメソッドです。
この中でshowDitailでセグエする場合の処理を書きます。
この中で編集されているセルが何番目のセルなのかを保持する方法がよーわからんかったので、DetailViewControllerにまで持って行って保持した。
Master画面でそれなりのプロパティをつくっておけばよかったのかな?
とりあえずDetailViewController.hにindexPathプロパティを作る。
#import <UIKit/UIKit.h> @interface DetailViewController : UIViewController //detilViewでの内容を保存するtodo @property (strong, nonatomic) NSDictionary *todo; //masterViewから渡されたセルの番号 @property (strong, nonatomic) NSIndexPath *indexPath; @end
んでからMasterViewController.mのprepareForSegueメソッドの内容を記述。
#pragma mark - Segues - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { //showDetailを通ったセグエの場合 if ([[segue identifier] isEqualToString:@"showDetail"]) { //選択されたセルのindexPathを取得 NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; //選択したパスの内容を一時的に保存 NSDictionary *todo = _objects[indexPath.row]; //遷移先のコントローラーにセルの内容と、セルの番号を送る。 UINavigationController *navigationController = segue.destinationViewController; DetailViewController *controller = (DetailViewController *)navigationController; controller.todo = todo; controller.indexPath = indexPath; } //セルの選択を解除。 [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; }
これで、セルの内容をDetail画面に送り出したわけですが、まだDetail画面の受け取り準備が出来てません。
Detail画面で受け取ったtodoの内容をそれぞれテキストフィールド、テキストビューに入れます。
DetailViewController.mのconfigureViewを修正します。
- (void)configureView { if (!self.todo) { //todoが何もない、新規で来た場合。新規作成。 _todo = @{ @"title":@"タイトル", @"body":@"内容"}; self.titleField.text = _todo[@"title"]; self.bodyTextView.text = _todo[@"body"]; } else { //todoが入ってた、送られてきた場合。 self.titleField.text = _todo[@"title"]; self.bodyTextView.text = _todo[@"body"]; } }
これでMaster画面から送られてきたセルの内容がDetail画面で表示されるようになりました。
しかしこのままでは保存ボタンを押すと新規のセルとして保存されてしまいますのでそれを修正します。
MasterViewController.mのunwindToMasterを編集します。
遷移先に送ってあったセルの番号を取得し、中身が無ければ新規保存、有るなら内容修正のメソッドに行くようにします。
- (IBAction)unwindToMaster:(UIStoryboardSegue *)segue { //segueの遷移先から帰ってきた時。 if ([segue.identifier isEqualToString:@"saveTodo"]) { //遷移先のビューを取得 DetailViewController *controller = (DetailViewController *)segue.sourceViewController; //遷移先に送ってあったセルの番号を取得。 NSIndexPath *indexPath = controller.indexPath; if (indexPath == nil) { // セルの番号がない時はタスク項目を追加する [self insertNewToDo:controller.todo]; } else { // セルの番号が有る時はタスクを編集する [self replaceToDoAtIndex:indexPath.row sender:controller.todo]; } } }
セルの内容修正のメソッドは
-(void)replaceToDoAtIndex:(NSInteger)index sender:(id)sender { //オブジェクトのインデックス番号に上書き。 [_objects replaceObjectAtIndex:index withObject:sender]; //テーブルビューを表示し直す。 [self.tableView reloadData]; }
これで新規でTODOを作る、作ったTODOをDetail画面で修正して戻るとこまで出来た。