2013-04-15 21 views
1

我無法從可可編程書​​籍中找到一個例子來工作(我認爲XCode已經過時的部分問題)。它沒有提到我需要做什麼來接收來自NSTableView的通知,而不是在IB中進行適當的連接。該應用程序是一個帶有用戶輸入的NSTextField的程序,當點擊一個按鈕時,NSSpeechSynthesizer的一個實例會說出輸入的行。我應該能夠通過選擇表視圖上的行來切換說話的聲音。我可以點擊,應用技術上的作品,但我無法通過點擊一排NSTableView的GUI上的更改默認說話的聲音:Objective-C/Cocoa/XCode新手:如何接收通知?

GUI inpterface

appdelegate.h:

#import <Cocoa/Cocoa.h> 

@interface AppDelegate : NSObject <NSApplicationDelegate,NSSpeechSynthesizerDelegate,NSTableViewDelegate> 
{ 
    NSArray *_voices; 
    NSSpeechSynthesizer *_speechSynth; 
} 

@property (assign) IBOutlet NSWindow *window; 
@property (weak) IBOutlet NSTextField *textField; 
@property (assign) IBOutlet NSTextField *text; 

@property (assign) IBOutlet NSButton *_speakButton; 
@property (assign) IBOutlet NSButton *_stopButton; 

@property (assign) IBOutlet NSTableView *table; 

-(IBAction)sayIt:(id)sender; 
-(IBAction)stopIt:(id)sender; 

@end 

的appdelegate .m:

#import "AppDelegate.h" 

@implementation AppDelegate 

@synthesize window = _window; 
@synthesize textField = _textField; 
@synthesize text = _text; 
@synthesize _speakButton; 
@synthesize _stopButton; 

@synthesize table; 

-(void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking 
{ 
    NSLog(@"finishedSpeaking=%d",finishedSpeaking); 
    [_speakButton setEnabled:YES]; 
    [_stopButton setEnabled:NO]; 
    [table setEnabled:YES]; 
} 

-(id)init 
{ 
    NSLog(@"init called"); 
    self = [super init]; 
    if (self) 
    { 
     NSLog(@"init"); 
     _speechSynth = [[NSSpeechSynthesizer alloc] initWithVoice:nil]; 
     [_speechSynth setDelegate:self]; 
     [_text setStringValue:@""]; 
     _voices = [NSSpeechSynthesizer availableVoices]; 
    } 

    //I added this line myself as I was trying to figure it out 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tableViewSelectionDidChange:) name:@"MyNotification" object:table]; 
    return self; 
} 
-(IBAction)sayIt:(id)sender 
{ 
    NSString *string = [_textField stringValue]; 
    if([string length]==0) 
    { 
     NSLog(@"string from %@ is of zero-length",_textField); 
     return; 
    } 
    [_speechSynth startSpeakingString:string]; 
    [_text setStringValue:[_speechSynth voice]]; 
    ... 
} 
-(IBAction)stopIt:(id)sender 
{ 
    NSLog(@"stopping"); 
    ... 
} 
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tv 
{ 
    return (NSInteger)[_voices count]; 
} 
-(id)tableView:(NSTableView *)tv 
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{ 
    NSString *v = [_voices objectAtIndex:row]; 
    NSDictionary *dict =[NSSpeechSynthesizer attributesForVoice:v]; 
    return [dict objectForKey:NSVoiceName]; 
} 

-(void)tableViewSelectionDidChange:(NSNotification *)notification 
{ 
    NSInteger row = [table selectedRow]; 
    if(row==-1) return; 
    NSString *selectedVoice = [_voices objectAtIndex:row]; 
    [_speechSynth setVoice:selectedVoice]; 
    NSLog(@"new voice = %@",selectedVoice); 
} 

-(void)awakeFromNib 
{ 
    NSLog(@"awakeFromNib"); 
    NSString *defaultVoice = [NSSpeechSynthesizer defaultVoice]; 
    NSInteger defaultRow = [_voices indexOfObject:defaultVoice]; 
    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:defaultRow]; 
    [table selectRowIndexes:indices byExtendingSelection:NO]; 
    [table scrollRowToVisible:defaultRow]; 
} 
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    NSLog(@"Appdidfinishlaunching called"); 
} 

@end 

我在猜測我弄錯了。我只需要有人指出我應該如何運作的正確方向。

+0

什麼不起作用?在我看來,它是完美的。您正在選擇Alex,文本字段顯示爲「com.apple.speech.synthesis.voice.Alex」。所以它會響應您的點擊。那究竟是什麼問題? – matt

+0

oops。我的意思是說,appdelegate不會點擊NSTableView來更改默認的語音選擇。 –

+0

但是很明顯,因爲屏幕顯示它是。該程序似乎正在完美工作。它可能沒有做你期望做的事,但它正在做它被做的事情。 – matt

回答

1

這裏有幾種可能的錯誤來源。

  • 您可能忘記將nib中的表格視圖掛接到應用程序代理,作爲其delegate

  • 您可能忘記將筆尖中的應用程序代理掛接到文本字段textField

    (還有其他的可能性(一個具有與筆尖鉤東西做的),但我不會列出所有的人......)

  • 如果你的目標真的是讓選擇消息一個通知,那麼這一行是錯誤的:

    [[NSNotificationCenter defaultCenter] 
        addObserver:self selector:@selector(tableViewSelectionDidChange:) 
        name:@"MyNotification" object:table]; 
    

    這個通知的名稱不是@"MyNotification";它是NSTableViewSelectionDidChangeNotification

+0

最後一個工作。謝謝! –

+0

是的,但第一個是最有可能的。沒有必要將此消息作爲通知來看,因爲您可以將其作爲委託消息來獲取。要小心,你不會得到它兩次! – matt