为NSOutlineView创建新的条目,重点突出并可编辑

时间:2013-05-20 12:21:27

标签: cocoa nsoutlineview

当在NSOutlineView中创建新项目时,我希望选择并编辑该项目,我目前在我的NSOutlineview委托/数据源中使用以下代码,新项目已创建,但它不是专注/可编辑。

NSWindow *w = [[self outlineView] window];
    BOOL endEdit = [w makeFirstResponder:w];
    if (!endEdit) {
        return;
    }

    NSUInteger row = [[self outlineView] rowForItem:newGoal];

    [[self outlineView] scrollRowToVisible:row];

    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:row];

    [[self outlineView] selectRowIndexes:indexSet byExtendingSelection:NO];

    [[self outlineView] editColumn:0
                               row:row
                         withEvent:nil
                            select:YES];
        NSError *anyError = nil;

        BOOL success = [[self myContext] save:&anyError];
        if (!success) {
            NSLog(@"Error = %@", anyError);
       }

我的完整档案是

    //
//  SBOutlineViewController.m
//  Allocator
//
//  Created by Cory Sullivan on 2013-04-21.
//  
//

#import "SBOutlineViewController.h"
#import "SBAppDelegate.h"


@interface SBOutlineViewController ()


@end

NSString * const SBOutlineSelectionChangedNotification = @"SBSelectionChanged";


@implementation SBOutlineViewController




- (void)awakeFromNib
{
    [self setTopLevelItems:[NSArray arrayWithObjects:@"Retirement", @"Education", nil]];
    [self setMyContext:[[NSApp delegate] managedObjectContext]];

    [self updateOutlineView];

}

- (void)updateOutlineView
{
    NSFetchRequest *myRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *goalEntity = [NSEntityDescription entityForName:@"Goal" inManagedObjectContext:[self myContext]];

    [myRequest setEntity:goalEntity];

    NSError *anyError = nil;


    [self setGoalItems:[[self myContext] executeFetchRequest:myRequest error:&anyError]];

    NSMutableArray *retirementArray = [[NSMutableArray alloc] init];
    NSMutableArray *educationArray = [[NSMutableArray alloc] init];

    for (NSManagedObject *goalObject in [self goalItems]) {
        if ([[goalObject valueForKey:@"goalType"] isEqual: @"Retirement"]) {

            [retirementArray addObject:goalObject];
        } else {
            if ([[goalObject valueForKey:@"goalType"] isEqual:@"Education"]) {

                [educationArray addObject:goalObject];
            }
        }
    }

[self setMyOutlineDictionary:[[NSMutableDictionary alloc] initWithObjectsAndKeys:retirementArray, @"Retirement", educationArray, @"Education", nil]];

[[self outlineView] reloadData];

}

#pragma mark - Delegate and DataSoure Methods

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    return [[self _childrenForItem:item] objectAtIndex:index];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    if ([outlineView parentForItem:item] == nil) {
        return YES;
    } else {
        return NO;
    }
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
    if ([outlineView parentForItem:item] == nil) {
        return NO;
    } else {
        return YES;
    }

}

- (NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    return [[self _childrenForItem:item] count];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
    return [_topLevelItems containsObject:item];
}


- (void)outlineViewSelectionDidChange:(NSNotification *)notification {

    if ([_outlineView selectedRow] != -1) {

        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
        [nc postNotificationName:SBOutlineSelectionChangedNotification object:self];
    }
}

- (NSArray *)_childrenForItem:(id)item {
    NSArray *children;
    if (item == nil) {
        children = _topLevelItems;
    } else {
        children = [_myOutlineDictionary objectForKey:item];
    }
    return children;
}


- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    NSTableCellView *view = nil;

    if ([_topLevelItems containsObject:item]) {

        view  = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
        NSString *value = [item uppercaseString];
        [[view textField] setStringValue:value];
        return view;

    } else {
        view = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
        [[view imageView] setImage:[NSImage imageNamed:NSImageNameActionTemplate]];
        NSManagedObject *goalItem = [_goalItems objectAtIndex:[_goalItems indexOfObject:item]];

        [[view textField] setStringValue:[goalItem valueForKey:@"goalName"]];
         return view;
    }
}

#pragma mark - Custom Actions


- (IBAction)goalActionPullDown:(id)sender
{
    [self modifyGoalItems: [[sender selectedItem] tag]];
}

- (void)modifyGoalItems:(NSInteger)whichMenuTag
{
    if (whichMenuTag == 5) {
        NSAlert *alert = [NSAlert alertWithMessageText:@"Are you sure you want to delete goal and all related accounts?"
                                         defaultButton:@"Remove"
                                       alternateButton:@"Cancel"
                                           otherButton:nil
                             informativeTextWithFormat:@"This can't be undone"];
        [alert beginSheetModalForWindow:[_outlineView window]
                          modalDelegate:self
                         didEndSelector:@selector(alertEnded:code:context:)
                            contextInfo:NULL];
    } else {

        NSManagedObject *newGoal = [NSEntityDescription insertNewObjectForEntityForName:@"Goal" inManagedObjectContext:[self myContext]];

        switch (whichMenuTag) {
            case 1:
            {
                [newGoal setValue:@"New Goal" forKey:@"goalName"];
                [newGoal setValue:@"Retirement" forKey:@"goalType"];
                [self updateOutlineView];
            }

                break;
            case 2:
            {
                [newGoal setValue:@"New Goal" forKey:@"goalName"];
                [newGoal setValue:@"Education" forKey:@"goalType"];
                [self updateOutlineView];
            }
                break;
            case 3:
                NSLog(@"You selected Item number 3");
                break;

            case 4:
                NSLog(@"You selected Item number 4");
                break;

            default:
                break;

        }

        NSWindow *w = [[self outlineView] window];
        BOOL endEdit = [w makeFirstResponder:w];
        if (!endEdit) {
            return;
        }

        NSUInteger row = [[self outlineView] rowForItem:newGoal];

        [[self outlineView] scrollRowToVisible:row];

        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:row];

        [[self outlineView] selectRowIndexes:indexSet byExtendingSelection:NO];

        [[self outlineView] editColumn:0
                                   row:row
                             withEvent:nil
                                select:YES];
            NSError *anyError = nil;

            BOOL success = [[self myContext] save:&anyError];
            if (!success) {
                NSLog(@"Error = %@", anyError);
           }
    }
}

- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
    return YES;
}


- (void)alertEnded:(NSAlert *)alert
              code:(int)choice
           context:(void *)v
{

    if (choice == NSAlertDefaultReturn) {
        NSManagedObject *selectedGoal = [[self outlineView] itemAtRow:[[self outlineView] selectedRow]];
        [[self myContext] deleteObject:selectedGoal];

        NSError *anyError = nil;

        BOOL success = [[self myContext] save:&anyError];
        if (!success) {
            NSLog(@"Error = %@", anyError);
        }

        [self updateOutlineView];

    }
}


@end

1 个答案:

答案 0 :(得分:1)

任何尝试使该字段在当前通过运行循环的过程中都可编辑将失败。你需要做的是在循环中下一次提示选择。像这样:

    [self performSelector:@selector(selectText:) withObject:textField afterDelay:0];

您可能希望在文本字段上执行selectText以外的操作,但该技术是您所需要的。