Can't edit cells in TahDoodle


#1

I’ve gotten through the code and XIB changes through page 277. The book indicates that at this I should be able to run TahDoodle, that is, I should be able to click the button to add a row to the table view and double-click the row to edit its contents. This doesn’t seem to be working. I left the NSLog statement attached to the button, and that seems to be working. I don’t know if cells are being added, and there doesn’t seem to be a way to add text. When I click on anything on the TahDoodle table and try to type, no letters appear and the beep of denial sounds.

The references made in xib seem to be ok. I checked through the code, and it seems to be ok. Suggestions?

//  Document.m
//  TahDoodle
//
//  Created by Emily Dean on 12/11/14.
//  Copyright (c) 2014 Big Nerd Ranch. All rights reserved.
//

#import "Document.h"

@interface Document ()

@end

@implementation Document

# pragma mark Data Source Methods

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    // This table view displays the tasks array,
    // so the number of entries in the table view will be the same
    // as the number of objects in the array
    return [self.tasks count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    // Return the item from tasks that corresponds to the cell
    // that the table view wants to display
    
    return [self.tasks objectAtIndex:row];
}

- (void)tableView:(NSTableView *)tableView
   setObjectValue:(id)object
   forTableColumn:(NSTableColumn *)tableColumn
              row:(NSInteger)row
{
    // When the user changes a task on the table view
    // update the tasks in the array
    [self.tasks replaceObjectAtIndex:row withObject:object];
    
    // And then flag the document as having unsaved changes
    [self updateChangeCount:NSChangeDone];
}

# pragma mark -- NSDocument Overrides

- (instancetype)init {
    self = [super init];
    if (self) {
        // Add your subclass-specific initialization here.
    }
    return self;
}

- (void)windowControllerDidLoadNib:(NSWindowController *)aController {
    [super windowControllerDidLoadNib:aController];
    // Add any code here that needs to be executed once the windowController has loaded the document's window.
}

+ (BOOL)autosavesInPlace {
    return YES;
}

- (NSString *)windowNibName {
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @"Document";
}

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
    // Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning nil.
    // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
    [NSException raise:@"UnimplementedMethod" format:@"%@ is unimplemented", NSStringFromSelector(_cmd)];
    return nil;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
    // Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO.
    // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
    // If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.
    [NSException raise:@"UnimplementedMethod" format:@"%@ is unimplemented", NSStringFromSelector(_cmd)];
    return YES;
}

# pragma mark -- Actions

- (void)addTask:(id)sender
{
    // If there is no array yet, create one
    NSLog(@"Add task button clicked.");
    
    if (!self) {
        self.tasks = [NSMutableArray array];
    }
    
    [self.tasks addObject:@"New Item"];
    
    // - reload data asks the table to refresh and ask its dataSource
    // (which happens to be this Document object in this case)
    // for new data to display
    [self.taskTable reloadData];
    
    // -updateChangeCount tells the application whether or not the document
    // has unsaved changes, NSChangeDone flags the document as unsaved
    [self updateChangeCount:NSChangeDone];
}

@end

#2

What kind of TableView did you configure? There are two kinds: view-based and cell-based.

You should probably be using a cell-based TableView.

[Become a competent programmer faster than you can imagine: pretty-function.org]


#3

Thanks for the suggestion. I am using a cell-based TableView.

Ok… found it. The problem was in the initializing of the array. I had (!self) instead of (!self.tasks) in the if statement.

Just a reminder that troubleshooting is part of this game…