2

概要:

次のiOSプロジェクトがあります。

  • コア データ (を使用NSFetchedResultsController)
  • データを表形式で表示 ( UITableView)

私がしたいこと:

  • ユーザーがレコードを追加すると、新しく追加されたレコードまでスクロールしたい。

私がやった事

  1. 新しいレコードが追加されると、メソッド内で、タイプが挿入/更新/移動の場合、NSFetchedResultsControllerDelegateインデックス パスをプロパティに保存します。lastAddedIndexPath
  2. 保存を呼び出した後、「lastAddedIndexPath」までスクロールします

コード (NSFetchedResultsControllerDelegate)

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{       
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    {
        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store insert - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store update - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store move - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;
        }
    }
}

スクロールするコード

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (self.beganUpdates) //already [self.tableView beginUpdates] invoked
    {
        [self scrollToLastAddedIndexPath];  //contains the logic to scroll
        [self.tableView endUpdates];   
    }
}

問題

  • レコードは、別のスレッドで非同期にテーブル ビューに追加されていると思います。
  • そのため、データベースを保存した後でもlastAddedIndexPath、テーブル内のレコードまでスクロールすると、まだ存在しません。

質問

  1. レコードがテーブル ビューに追加された後、新しく追加されたレコード パスにスクロールするにはどうすればよいですか?
  2. データベースがいつ保存されたかを知るために通知を使用する必要がありますか?
  3. 他の代替アプローチはありますか?
4

3 に答える 3

5

[self.tableView endUpdates]新しい行はその時点までテーブルに追加されないため、スクロールは後で行う必要があります。したがって、2つのステートメントを入れ替えます。

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    if (self.beganUpdates) //already [self.tableView beginUpdates] invoked 
    { 
        [self.tableView endUpdates]; 
        [self scrollToLastAddedIndexPath];  //contains the logic to scroll 

    } 
} 
于 2012-04-18T07:44:02.467 に答える
1

スクロールは次の場所で実行する必要があります。

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

または、KVO を使用して、新しいレコードが追加されたときに通知を受けることもできます。

于 2012-04-18T05:45:25.537 に答える
0

私のシナリオでは、最後に追加されたオブジェクトをテーブル ビューの上に表示する必要があるため、別のアプローチを使用しました。NSSortDescriptor を使用して配列を並べ替え、レコードを追加/削除するたびにテーブル ビューをリロードしました。このような

NSSortDescriptor * sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]autorelease];
NSArray * sortDescriptorArray = [[[NSArray alloc] initWithObjects:sortDescriptor,nil]autorelease];

self.commitsList =  [[self.listItem.itemCommit allObjects] sortedArrayUsingDescriptors:sortDescriptorArray];

[tblView reloadData];

次に、データに関連する任意のキーを使用してinitWithKey、配列を並べ替えてこれを解決できます。テーブルビューのCellForRowIndex方法では、この配列を使用してテーブルビューにデータを入力できます。

于 2012-04-18T06:10:57.000 に答える