1

コアデータにデータを保存するときに問題が発生し、行の編成にも問題があります。問題が何であるかをよりよく理解するために、私が持っているものを説明します。

動的行を操作するメインのテーブルビューがあります。このテーブルビューには + ボタンがあります。+ ボタンを押すと、ポップオーバー内にテーブルビューが表示され、ユーザーはメインのテーブルビューに挿入する「セルの種類」を選択できます。「セルのタイプ」はカスタムセルであり、それらは1つのクラスとxibファイルです。各カスタムセルにはさまざまなテキストフィールドがあります...つまり、アイデアは次のとおりです。

  1. セルのタイプを選択し、メインのテーブルビューに挿入します。
  2. テキストフィールドにデータを入力します。
  3. 保存されるデータは、挿入された行数とテキストフィールドのデータに対応します。

ポップオーバーテーブルビューを呼び出すとき、メインテーブルビューにこのメソッドがあります:

- (IBAction)Add:(id)sender
{

SelectProduct *typeProduct=[[self.storyboard instantiateViewControllerWithIdentifier:@"selectTable"]initWithTableViewTag:self.tableView.tag];
self.popover=[[UIPopoverController alloc]initWithContentViewController:typeProduct];
[popover presentPopoverFromBarButtonItem:buttonAdd permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
typeProduct.popView = self.popover;
typeProduct.cellSelected = self.cellSelected; //cellSelected is core data subclass.
typeProduct.delegate = self;
typeProduct.managedObjectContext = self.managedObjectContext;
}

次に、ポップオーバーテーブルビューの didSelectRow に、次のものがあります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
row = indexPath.row;

if (row == 0)
{
    cellSelected=[NSEntityDescription insertNewObjectForEntityForName:@"CellSave" inManagedObjectContext:self.managedObjectContext];
    cellSelected.nameCellData = @"Olive";
    cellSelected.amountData = myCostumCell.amount.text;   
}

ここから、メインのテーブルビューにセルが挿入されます。メインのテーブルビューに関連するメソッドは次のとおりです。

- (void)viewDidLoad
{
[self.tableView registerNib:[UINib nibWithNibName:@"myCostumCellXib" bundle:nil] forCellReuseIdentifier:@"myCostumCell"];

AppDelegate *appDelegate =[[UIApplication sharedApplication] delegate];
self.managedObjectContext=[appDelegate managedObjectContext];

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) 
{
    // Replace this implementation with code to handle the error appropriately.
    // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

[self fetchedResultsController];
}

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

{
static NSString *CellIdentifier = @"myCostumCell";

cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.cellSelected = self.cellSelected;
cell.managedObjectContext = self.managedObjectContext;

if (cell == nil)
{
    cell = [[MyCostumCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.nameCell.text = cellSelected.nameCellData;

if ([cellSelected.nameCellData isEqualToString:@"Olive"])
   {
    cell.amount.text = cellSelected.amountData;
    // i have more textfields to assign but i think you understand the rest..
   }
}

私の fetchedResultsController メソッド: (他にもありますが、それらは標準的なものです)

- (NSFetchedResultsController *)fetchedResultsController
{

if (_fetchedResultsController != nil)
{
    return _fetchedResultsController;
}

// Create and configure a fetch request.
NSFetchRequest *fetchRequestCellSave = [[NSFetchRequest alloc] init];
NSEntityDescription *entityCellSave=
[NSEntityDescription entityForName:@"CellSave" inManagedObjectContext:self.managedObjectContext];
[fetchRequestCellSave setEntity:entityCellSave];

// Create the sort descriptors array.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"nameCellData" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequestCellSave setSortDescriptors:sortDescriptors];

_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestCellSave managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"nameCellData" cacheName:nil];
_fetchedResultsController.delegate = self;
self.fetchedResultsController = _fetchedResultsController;

return _fetchedResultsController;


}

ここで、メインのテーブルビューを終了して別のテーブルビューに移動したい場合、テキストフィールドの内容を managedObject に保存する必要があることを理解しています。

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];

    cellSelected.amountData = cell.amount.text;

    //i have more textfields to assign but for the example i think you understand
      what i want.

    [self.managedObjectContext save:nil];

}

ここから、1行が「保存」され、金額のテキストも...しかし、もう1行追加すると問題が発生します。

  1. 前の行が挿入された後ではなく、テーブルビューの上に新しい行が表示されるのはなぜですか?

  2. 挿入された 2 行目の textField (金額) を入力すると...テーブルビューを終了して戻ってきます...テキストフィールドが入力されていないように見えます..何が間違っていますか?

  3. 一度に2行を挿入すると前の問題が発生しますが、1つ挿入すると...テーブルビューを終了してから戻って別の行を挿入すると...テキストフィールドの量が保存されます...

私の問題はどこですか?それは私のカスタムセルクラスにありますか? どこ?...長い投稿で申し訳ありませんが、これは私を夢中にさせています...

御時間ありがとうございます

よろしく

4

1 に答える 1

1

ビューが表示から削除されたときだけでなく、データが入力されたらすぐにデータを保存する必要があります。セルが画面外にスクロールされるとすぐに再利用または強制終了されるため、その前にテキストを保存する必要があります。最適な場所は、テキストが変更されたときのテキスト フィールド デリゲート コールバックです。

保存する前に 2 行を追加すると、内部状態が破損します (2 行目が追加されたが、最初の行のデータをまだ保存していない場合)。

行は入力されたテキストでソートされるため、テキスト (またはテキストの欠落) に応じて、画面上のどこに表示されるかが決まります。

おそらく、セルに管理対象オブジェクト コンテキスト (MVC ではない) への参照を与えるべきではありません。

コードが混乱しているように見えるので、ローカル変数とインスタンス変数の違いについても考える必要があります...

于 2013-04-22T22:52:49.127 に答える