0

エンティティにバインドされたバインドと、にバインドされたツリーがありNSTreeControllerます。ここで、「追加」ボタンをクリックしたときに、に新しいエンティティを追加し、エンティティを選択して、編集用に強調表示したいと思います。を呼び出すと、挿入は非同期になり、アウトラインビューでは新しい行が自動的に選択されないため、新しいオブジェクトがどれであるかを知る方法がありません。そのため、プログラムで新しいエンティティを挿入する必要があります。したがって、を呼び出します(以下を参照)。NSArrayControllerNSOutlineViewtreeController[arrayController add]addButtoncreateNewGroupoutlineViewController

繰り返しますが、新しいエンティティの挿入は同期プロセスではないようです。NSOutlineView後の次の行でそれを見つけることができませんcurrentObject = [NSEntityDescription...。そして、私はデータをリロードした後に試しました。そのため、アレイコントローラーの値の変化を観察する必要があります。この種の作業は、ほとんどの場合機能しますが、機能しない場合もあります。これはこの種のことへの正しいアプローチですか?

- (void) createNewGroup:(id)sender {
    NSInteger row = [myOutlineView selectedRow];
    if(row == -1) {
        [groupsController addObserver:self 
                           forKeyPath:IR_GROUPS_KEYPATH 
                              options:NSKeyValueObservingOptionInitial 
                              context:IR_GROUPS_CONTEXT];
        currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                      inManagedObjectContext:appDelegate.managedObjectContext];
        return;
    }
    if([myOutlineView levelForRow:row] != 0) return;
    [subGroupsController addObserver:self 
                          forKeyPath:IR_GROUPS_KEYPATH 
                             options:NSKeyValueObservingOptionInitial 
                             context:IR_SUBGROUPS_CONTEXT];
    NSManagedObject *parent = [[myOutlineView itemAtRow:row] representedObject];
    currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                            inManagedObjectContext:appDelegate.managedObjectContext];
    [currentObject setValue:parent forKey:@"parent"];
}

- (void) observeValueForKeyPath:(NSString *)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary *)change 
                        context:(void *)context {

    if([keyPath isEqualToString:IR_GROUPS_KEYPATH]) {
        if(currentObject == nil) return;
        [myOutlineView noteNumberOfRowsChanged];
        NSString *ctx = (NSString *) context;
        if([ctx isEqualToString:IR_GROUPS_CONTEXT]) {

            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    // We found the new object:
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
            //[groupsController removeObserver:self forKeyPath:nil];

        } else if([ctx isEqualToString:IR_SUBGROUPS_CONTEXT]) {
            NSTreeNode *parent = [myOutlineView itemAtRow:[myOutlineView selectedRow]];
            [myOutlineView expandItem:parent];
            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
        }
    }
}
4

1 に答える 1

1

NSTreeController(のサブクラス)を使用してoutlineViewのコンテンツを提供する場合、それは非常に簡単です。コードまたはInterfaceBuilderのいずれかでボタンを作成し、ターゲットをバインドしinsert:て要素を追加またはremove:削除するように設定します。コードでは、次のようになります。

[aButton bind:NSTargetBinding 
     toObject:aController 
  withKeyPath:keyPathToTreeController
    options:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSConditionallySetsEnabledBindingOption,
                             @"insert:", NSSelectorNameBindingOption,
                             nil]];

新しいオブジェクトの選択は、treeControllerによって処理されます。繰り返しますが、コードでは:

[aTreeController setSelectsInsertedObjects:YES];

IBでは、チェックする必要があるチェックボックスです。ああ、もありaddChild:ます。バインディングに魔法をかけてもらいましょう。

于 2011-04-23T16:11:58.033 に答える