2009-07-29 6 views
0

개요보기와 버튼이 있습니다. 개요보기에서 선택한 행을 단추가 제거하도록합니다. 개요보기의 선택 색인 경로를 트리 컨트롤러에 바인딩하고 단추를 트리 컨트롤러의 remove: 선택기에 연결 한 다음 단추를 트리 컨트롤러의 canRemove: 속성에 바인딩했습니다. 그러나 일단 (내가 예상했던) 모든 작업을 완료하면 개요보기가 완전히 끊어집니다. 중단이라고 말하면 더 이상 작동하지 않는다는 의미이며, 추가 한 데이터는 표시되지 않습니다.개요보기에서 행 삭제

이제 몇 가지 추가 정보를 보려면 어레이 컨트롤러와 트리 컨트롤러의 연결 그림을 참조하십시오.

NSArrayController 연결

alt text http://snapplr.com/snap/b5a1

NSTreeController 연결

(당신이 선택 인덱스 경로 바인딩없이 볼 수 있듯이) alt text http://snapplr.com/snap/qv62

한 최종 것은, 개요보기가 끌어서 놓기 작업을 수행 할 수있는 데이터 소스. 작동하지 않는 것과 관련이 있기 때문에 아래에는 데이터 소스의 코드가 나와 있습니다.

구현 파일.

#import "DragController.h" 


@implementation DragController 
- (void)awakeFromNib { 

    dragType = [NSArray arrayWithObjects: @"factorialDragType", nil]; 

    [ dragType retain ]; 

    [ treeTable registerForDraggedTypes:dragType ]; 
    NSSortDescriptor* sortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES]; 
    [groupTreeControl setSortDescriptors:[NSArray arrayWithObject: sortDesc]]; 
    [ sortDesc release ]; 
} 


//------------------------------------ 
#pragma mark NSOutlineView datasource methods -- see NSOutlineViewDataSource 
//--------------------------------------------------------------------------- 
- (BOOL) outlineView : (NSOutlineView *) outlineView 
      writeItems : (NSArray*) items 
     toPasteboard : (NSPasteboard*) pboard { 

    [ pboard declareTypes:dragType owner:self ];   
    // items is an array of _NSArrayControllerTreeNode see http://theocacao.com/document.page/130 for more info 
    draggedNode = [ items objectAtIndex:0 ]; 

    return YES; 
} 




- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index { 

    _NSArrayControllerTreeNode* parentNode = item; 
    _NSArrayControllerTreeNode* siblingNode; 
    _NSControllerTreeProxy* proxy = [ groupTreeControl arrangedObjects ]; 

    NSManagedObject* draggedGroup = [ draggedNode observedObject ]; 

    BOOL draggingDown = NO; 
    BOOL isRootLevelDrag = NO; 

    // ---------------------- 
    // Setup comparison paths 
    // ------------------------- 
    NSIndexPath* draggedPath = [ draggedNode indexPath ]; 
    NSIndexPath* siblingPath = [ NSIndexPath indexPathWithIndex: index ]; 
    if (parentNode == NULL) {  
     isRootLevelDrag = YES; 
    } else { 
     // A non-root drag - the index value is relative to this parent's children 
     siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index ]; 
    } 

    // ---------------------- 
    // Compare paths - modify sibling path for down drags, exit for redundant drags 
    // -----------------------------------------------------------------------------  
    switch ([ draggedPath compare:siblingPath]) { 
     case NSOrderedAscending: // reset path for down dragging 
      if (isRootLevelDrag) { 
       siblingPath = [ NSIndexPath indexPathWithIndex: index - 1];        
      } else { 
       siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index - 1 ]; 
      } 
      draggingDown = YES; 
      break; 

     case NSOrderedSame: 
      return NO; 
      break;    
    } 

    siblingNode = [ proxy nodeAtIndexPath:siblingPath ];  

    // NSLog(@"returning early"); 
    // return NO; // TODO robustify 


    // ------------------------------------------------------------ 
    // SPECIAL CASE: Dragging to the bottom 
    // ------------------------------------------------------------ 
    // - K        - K       - C        - C 
    // - - U        - - C  OR  - U        - F 
    // - - C  ====>  - - F     - F        - K 
    // - - F    - U    - K        - U 
    // ------------------------------------------------------------ 
    if (isRootLevelDrag && siblingNode == NULL) {   
     draggingDown = YES; 
     siblingPath = [ NSIndexPath indexPathWithIndex: [ proxy count ] - 1 ];   
     siblingNode = [ proxy nodeAtIndexPath:siblingPath ] ; 
    } 

    // ------------------------------------------------------------ 
    // Give the dragged item a position relative to it's new sibling 
    // ------------------------------------------------------------ 
    NSManagedObject* sibling = [ siblingNode observedObject ]; 
    NSNumber* bystanderPosition = [ sibling valueForKey:@"position"]; 
    int newPos = (draggingDown ? [ bystanderPosition intValue ] + 1 : [ bystanderPosition intValue ] - 1); 
    [draggedGroup setValue:[ NSNumber numberWithInt:newPos ] forKey:@"position"]; 

    // ---------------------------------------------------------------------------------------------- 
    // Set the new parent for the dragged item, resort the position attributes and refresh the tree 
    // ----------------------------------------------------------------------------------------------  
    [ draggedGroup setValue:[ parentNode observedObject ] forKey:@"parent" ]; 
    [ self resortGroups:[draggedGroup managedObjectContext] forParent:[ parentNode observedObject ] ];   
    [ groupTreeControl rearrangeObjects ]; 
    return YES;    
} 






- (NSArray*) getSubGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent { 
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"projects" inManagedObjectContext:objectContext]; 

    [request setEntity:entity]; 
    NSSortDescriptor* aSortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES]; 
    [request setSortDescriptors:[NSArray arrayWithObject: aSortDesc] ]; 
    [aSortDesc release]; 

    NSPredicate* validationPredicate = [NSPredicate predicateWithFormat:@"parent == %@", parent ]; 

    [ request setPredicate:validationPredicate ]; 

    NSError *error = nil; // TODO - check the error bozo 
    return [objectContext executeFetchRequest:request error:&error];  
} 




- (void) resortGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent { 

    NSArray *array = [ self getSubGroups:objectContext forParent:parent ]; 

    // Reset the indexes... 
    NSEnumerator *enumerator = [array objectEnumerator]; 
    NSManagedObject* anObject; 
    int index = 0; 
    while (anObject = [enumerator nextObject]) { 
     // Multiply index by 10 to make dragging code easier to implement ;) .... 
     [anObject setValue:[ NSNumber numberWithInt:(index * INTERVAL) ] forKey:@"position"];  
     index++; 
    } 


} 

- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index { 

    _NSArrayControllerTreeNode* newParent = item; 

    // drags to the root are always acceptable 
    if (newParent == NULL) { 
     return NSDragOperationGeneric; 
    } 

    // Verify that we are not dragging a parent to one of it's ancestors 
    // causes a parent loop where a group of nodes point to each other and disappear 
    // from the control 
    NSManagedObject* dragged = [ draggedNode observedObject ];  
    NSManagedObject* newP = [ newParent observedObject ]; 

    if ([ self category:dragged isSubCategoryOf:newP ]) { 
     return NO; 
    }  

    return NSDragOperationGeneric; 
} 

- (BOOL) category:(NSManagedObject*)cat isSubCategoryOf:(NSManagedObject*) possibleSub { 

    // Depends on your interpretation of subCategory .... 
    if (cat == possibleSub) { return YES; } 

    NSManagedObject* possSubParent = [possibleSub valueForKey:@"parent"]; 

    if (possSubParent == NULL) { return NO; } 

    while (possSubParent != NULL) {  
     if (possSubParent == cat) { return YES; } 

     // move up the tree 
     possSubParent = [possSubParent valueForKey:@"parent"];   
    } 

    return NO; 
} 




// This method gets called by the framework but the values from bindings are used instead 
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    return NULL; 
} 

/* 
The following are implemented as stubs because they are required when 
implementing an NSOutlineViewDataSource. Because we use bindings on the 
table column these methods are never called. The NSLog statements have been 
included to prove that these methods are not called. 
*/ 
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { 
    NSLog(@"numberOfChildrenOfItem"); 
    return 1; 
} 

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { 
    NSLog(@"isItemExpandable"); 
    return NO; 
} 

- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item { 
    NSLog(@"child of Item"); 
    return NULL; 
} 



@end 

답변

1

나는 그것을 알아 냈으므로 같은 문제가있는 모든 사람들을 돕기 위해 답을 게시 할 것입니다. 간단히이 문제를 해결하십시오.

  1. 바인드 직접 AppDelegate에의 managedObjectContext 속성에 NSTreeController의 managedObjectContext 및 전체 NSArrayController를 제거합니다. NSTreeController는 읽기 전용이므로 managedObjectContext에서 항목을 추가/제거 할 수 있지만 NSArrayController의 arrangedObjects에서는 항목을 추가/제거 할 수 없습니다.

  2. 이제 추가 버튼을 트리 컨트롤러의 add: 연결에 연결하십시오.

  3. 마지막으로 제거 단추를 트리 컨트롤러의 remove: 연결에 연결하십시오.

0

add:

  • 최근 버튼 (D ...
  • 최근 버튼 (N ...

그 "새"하고 "삭제"?

그렇다면 삭제 버튼을 add: 동작에 연결 한 상태로 두었습니다. 대신 remove:에 연결하십시오.

(또한, 버튼이 중단 된 것에 대한 설명은 the HIG을 행동이의 예를 들어 시스템 환경 설정의 계정 패널을 참조하십시오. 구두 라벨 오목한 버튼 대신 NSAddTemplate 및 NSRemoveTemplate 이미지 그라데이션 버튼을 사용한다)

+0

아니요 D는 완료라는 다른 버튼입니다. – Joshua