ドキュメントベースの ARC を使用するアプリケーションで NSTokenField の簡単な最初の例を試し、Document クラスを NSTokenFieldDelegate にしました。それは機能しますが、デリゲートメソッド tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: は、トークンの文字列の最初ではないトークンを正常に編集した場合でも、indexOfToken に 0 以外は表示されません。OS X 10.8.2 と 10.8 フレームワークで XCode 4.5 を使用しています。
質問: なぜ常に 0 なのですか? ユーザーが編集しているフィールドの間接的に見えるトークンの配列 0 .. n - 1 のトークンのインデックスであると思います。
再現するには、上記のようにプロジェクトを開始し、以下のテキストを追加します。次に、XIB エディターを使用して NSTokenField をドキュメント ウィンドウにドラッグし、トークン フィールドをドキュメントの tokenField として設定し、ドキュメント インスタンスをトークン フィールドのデリゲートにします。
Document.h :
#import <Cocoa/Cocoa.h>
@interface Document : NSDocument <NSTokenFieldDelegate>
{
IBOutlet NSTokenField *tokenField; // of (Token *).
NSMutableDictionary *tokens; // of (Token *).
}
@end
Token.h :
#import <Foundation/Foundation.h>
@interface Token : NSObject
@property (strong, nonatomic) NSString *spelling;
- (id)initWithSpelling:(NSString *)s;
@end
Token.m :
#import "Token.h"
@implementation Token
@synthesize spelling;
- (id)initWithSpelling:(NSString *)s
{
self = [super init];
if (self)
spelling = s;
return self;
}
@end
Document.m :
#import "Document.h"
#import "Token.h"
@implementation Document
- (id)init
{
self = [super init];
if (self) {
tokens = [NSMutableDictionary dictionary];
}
return self;
}
...
#pragma mark NSTokenFieldDelegate methods
- (NSArray *)tokenField:(NSTokenField *)tokenField
completionsForSubstring:(NSString *)substring
indexOfToken:(NSInteger)tokenIndex
indexOfSelectedItem:(NSInteger *)selectedIndex
{
NSLog(@"tokenField:completionsForSubstring:\"%@\" indexOfToken:%ld indexOfSelectedItem:",
substring, tokenIndex);
NSMutableArray *result = [NSMutableArray array];
for (NSString *key in tokens) {
//NSLog(@"match? \"%@\"", key);
if ([key hasPrefix:substring])
[result addObject:key];
}
return result;
}
- (id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString:(NSString *)editingString
{
NSLog(@"tokenField:representedObjectForEditingString:\"%@\"", editingString);
Token *token;
if ((token = [tokens objectForKey:editingString]) == nil) {
token = [[Token alloc] initWithSpelling:editingString];
[tokens setObject:token forKey:editingString];
//NSLog(@"token %@", [token description]);
NSLog(@"tokens %@", [tokens description]);
}
return token;
}
- (NSString *)tokenField:(NSTokenField *)tokenField displayStringForRepresentedObject:(id)representedObject
{
NSString *spelling = [representedObject spelling];
NSLog(@"tokenField:displayStringForRepresentedObject: = \"%@\"", spelling);
return spelling;
}
@end
トークンの入力は、改行またはコンマ文字で終了します。