■[iPhone開発記事]TabbarでCoreDataを使う(カスタムセルを使用)2
すいません、おそらくこっちの記事のほうが正確です。
この記事、TabbarでCoreDataを使う - ガジェット充まゆたまのiPhone開発とかいろいろ逆引きメモ SQLの名前を自分のプロジェクト名にしなければならない等、一部説明が飛んでいました。詳しい導入方法は以下のサンプルのReadMeをご覧ください。
長いのでポイントだけ。サンプルはこちらです。GitHub - prince9/TabCoreDataTempNew: (Sorry,Japanese only)CoreDataを使い、Tab1で入力したテキストをTab3のセルに書き込みます。TableViewContorollerを使わず、ViewContorollerにTableViewを設置してかつCoreDataを使うサンプルです
今回のポイントは以下になります。
・CoreDataを使い、Tab1で入力したテキストをTab3のTableViewに書き込む
・カスタムセルにCoreDataのデータを書き込む
・カスタムセルに書き込まれたデータを次のVIewで閲覧できるようにする(セルをクリックすると詳細を表示するViewに飛ぶ)
まず、CoreDataを使い、Tab1で入力したテキストをTab3のTableViewに書き込むことから。
これはTab1のTextFieldにテキストを入力してボタンを押すと、NotificationによってTab3の「- (void)insertNewObject」が呼び出されてTableViewに書き込まれます。
その際、注意点があります。それは「Tabbarはタブをタップしない限りViewが作られない」ということです。
ですので、擬似的にTab3をタップしてあげないといけません。が、前の記事にも書いた通りイマイチ上手くいかず、以下の力技を用いています。
- (void)viewWillAppear:(BOOL)animated { //セルのあるタブを選択したことにする UITabBarController *controller = self.tabBarController; controller.selectedViewController = [controller.viewControllers objectAtIndex: 2]; //0.05秒後に1つ目のタブ(Tab1ViewController)に戻る [self performSelector:@selector(delayTab) withObject:nil afterDelay:0.05f]; [super viewWillAppear:animated]; } //1つ目のタブ(Tab1ViewController)に戻る - (void)delayTab { UITabBarController *controller = self.tabBarController; controller.selectedViewController = [controller.viewControllers objectAtIndex: 0]; }
次、「カスタムセルにCoreDataのデータを書き込む」です。
これはそんなに複雑ではなく、UIViewrControllerにTableViewとTableView Cellを配置して結びつけるだけです。
が、ここも注意点があります。
Storyboardで結びつけをする場合、TableViewの中身のLabelやImageVIewは結びつけてはいけません。エラーが出ます。TableViewを結びつけて、LabelやImageViewの「Tag」をStoryboardとコードそれぞれに設定します。
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { //現在の行に表示するデータを取得 NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath]; //日時を日本時間に変換 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy年 MM/dd HH:mm"]; NSString *dateString = [formatter stringFromDate:[managedObject valueForKey:@"timeStamp"]]; //上からデータを取り出してテキストに設定 //storyboardでTableViewを設置した場合はLabelやImageViewをひも付けないこと //タグを設定することでどれがどれか識別できる。storyboardの「Tag」で設定してから以下に入力する dateText = (UILabel*)[cell viewWithTag:1]; subText1 = (UILabel*)[cell viewWithTag:2]; subText2 = (UILabel*)[cell viewWithTag:3]; dateText.text = dateString; subText1.text = [managedObject valueForKey:@"addText"]; subText2.text = [managedObject valueForKey:@"addText2"];
そして最後の「セルをクリックすると詳細を表示するViewに飛ぶ」です。これは前にCoreDataの記事を書いたときに書き忘れてしまったので、ここで補足しておきます。
・Tableが表示されているViewの.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showDetail"]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath]; DetailViewController *detailViewController = [segue destinationViewController]; [detailViewController setDetailItem:selectedObject]; //DetailViewControllerでセルの中身を表示できるよう準備する detailViewController.myStr = [selectedObject valueForKey:@"addText"]; detailViewController.myStr3 = [selectedObject valueForKey:@"addText2"]; //日時を日本時間に変更 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy年 MM/dd HH:mm"]; NSString *dateString2 = [formatter stringFromDate:[selectedObject valueForKey:@"timeStamp"]]; detailViewController.myStr2 = dateString2; } }
・セルのデータの詳細を表示するViewの.h
@interface DetailViewController : UIViewController { NSString *myStr; NSString *myStr2; NSString *myStr3; } ...
・セルのデータの詳細を表示するViewの.m
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. myLabel.text = myStr; detailDescriptionLabel.text = myStr2; myLabel2.text = myStr3; } ...