1

再びchildLevelsを含むことができるレベルを含むCoreDataモデルがあります。

UITableViewController私はすべてのchildLevelsのリストで各レベルを表します。ユーザーが行をタップすると、新しいUITableViewControllerものがにプッシュされますnavigationController。ここでは問題ありません。

このテーブル構造内にユーザーの場所を保存するにはどうすればよいですか。これを行うためのベストプラクティスはありますか?構造物の深さがわかっていれば問題ありませんが、深さを定義せずにこれにアプローチする方法に戸惑いました。

NSIndexPathユーザーがタップしたものを配列に保存してディスクに書き込む必要がありますか?

4

3 に答える 3

1

ユーザーがタップしたNSIndexPathsを使用する代わりに、基盤となるNSManagedObjectsを使用しました。これは、はるかに安全で(オブジェクトの数や並べ替えが変更された場合)、高速です(fetchRequestやビュー全体が必要ないため)。

UINavigationControllerをサブクラス化し、次のことを行いました。

レベル(に格納されている)の新しいTableViewControllerをプッシュするとき、parentLevelこれをUserDefaultsの配列に追加します。

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
   [super pushViewController:viewController animated:animated];

   if([viewController isKindOfClass:[LevelTableViewController class]]){
       NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
       NSManagedObject *obj = [(LevelTableViewController*)viewController parentLevel];

       if(obj!=nil){
         [array addObject:[[obj objectID].URIRepresentation absoluteString]];
       } 

       [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];

   }
}

viewControllerをポップすると、その配列から最後のエントリを削除するだけです。

- (UIViewController *) popViewControllerAnimated:(BOOL)animated{
  UIViewController *vc = [super popViewControllerAnimated:animated];
  // remove last object
  if([vc isKindOfClass:[LevelTableViewController class]]){
     NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
     [array removeLastObject];
     [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];
  }

  return vc;
}

次に、アプリを起動してツリーを再構築するときにNavigationControllerを初期化するときに、この配列を使用できます。

- (LevelNavigationController*) initWithRootViewController:(LevelTableViewController*)vc {
if(self = [super initWithRootViewController:vc]){
    // Recreate structure from UserDefaults
    NSArray *array = [NSArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
    [[NSUserDefaults standardUserDefaults] setObject:nil forKey:LevelTablesPersistentKey]; // set the array to nil -> will be rebuild when pushing viewcontrollers onto navigation stack

    NSPersistentStoreCoordinator *persistentStoreCoordinator = ...; // pointer to coordinator 
            NSManagedObjectContext * managedObjectContext = ...; // pointer to your context
    for (NSString *objId in array) {
        NSManagedObjectID *mobjId=[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objId]];
        if(mobjId!=nil){

            NSManagedObject *obj = nil;
            NSError **err = nil;
            obj = [managedObjectContext objectWithID:mobjId];

            if(err==nil && obj){
                if([obj.entity.name isEqualToString:@"Level"]){
                    // push level

                    LevelTableViewController *nextLevel = [[LevelTableViewController alloc] initWithStyle:UITableViewStylePlain];
                    nextLevel.parentLevel = (Level*)obj;
                    [self pushViewController:nextLevel animated:NO];
                    [nextLevel release];
                } 
            } 
        }
    }

}

return self;

}
于 2010-02-05T13:46:43.180 に答える
1

あなたの状態にを使用し、NSIndexPath永続性のためにそれを保存/復元することは私には理にかなっています。

また、プロパティリスト(plist)として格納されているNSArrayを使用するというアプローチは、かなり簡単なはずです。

于 2010-02-04T21:40:37.310 に答える
0

私は自分のアプリでこれを始める準備ができています。これが計画です。UIViewControllerが新しいビューをロードするたびに、NSUserDefaultsに値が作成され、その新しいビューに関する情報(開いた場所、入力されたデータなど)が示されます。サブビューが戻ると、ビューコントローラはこの値をクリアします。UIViewControllerに初期ロードがあると、デフォルトをチェックして、以前に値が格納されているかどうかを確認します。格納されている場合は、適切なアクションを実行してそのサブビューを再ロードします。このプロセスは、ナビゲーションチェーンの下流に続きます。

NSIndexPathの代わりにこれを行った理由は、メインビュー階層に加えて、多数の補助ビュー(追加、削除、編集など)があるためです。メインナビゲーションの外部に存在するこれらのビューの開始を記録する必要があるだけでなく、保存する必要のある状態の詳細(選択されたオプション、部分的に入力されたテキストなど)も多数含まれます。

私はここに戻って、それがたわごとの計画であることが判明した場合、これに反対票を投じます。

于 2010-02-04T22:00:10.837 に答える