1

ココアプログラミングの本から例を得ることができませんでした (問題の一部は、XCode が古くなっていることだと思います)。IBで適切な接続を行う以外に、NSTableViewから通知を受け取るために私がしなければならなかった特別なことは何も言及していませんでした。このアプリは、ユーザー入力用の NSTextField を持つプログラムであり、ボタンがクリックされると、NSSpeechSynthesizer のインスタンスが入力された行を読み上げます。テーブルビューの行を選択することで、話す声を切り替えることができるはずです。クリックできます。アプリは技術的には機能しますが、GUI の NSTableView の行をクリックしてデフォルトの話し声を変更することはできません。

GUI インターフェイス

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

私はこの方法を間違えたと思います。これがどのように機能するかを正しい方向に向けてくれる人が必要です。

4

1 に答える 1

1

ここには、いくつかのエラーの原因が考えられます。

  • nib のテーブル ビューをアプリのデリゲートにフックするのを忘れている可能性がありますdelegate

  • nib の app デリゲートをテキスト フィールドにフックするのを忘れているかもしれませんtextField

    (他にも可能性はありますが(ペン先に接続する必要があります)、すべてをリストすることはしません...)

  • 選択メッセージを通知として受け取ることが本当に目的である場合、次の行は間違っています。

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

    この通知の名前は ではありません@"MyNotification"。ですNSTableViewSelectionDidChangeNotification

于 2013-04-15T22:25:23.373 に答える