NSTokenField没有开火行动

Die*_*nné 2 macos cocoa action objective-c nstokenfield

我有一个NSTokenField向对象(文档)添加标签.我想在将令牌添加到令牌字段时(当键入令牌化字符时)使用新标签更新对象.不幸的是,这似乎不起作用.在NSTokenField连接到我的控制器的动作,但这个动作方法不会被调用.

我也NSTextField以相同的方式连接到控制器,并调用其在控制器中的操作方法.

我也用关键值观察来尝试这个:

- (void) awakeFromNib {
    [tokenField addObserver:self forKeyPath:@"objectValue" options:NSKeyValueObservingOptionNew context:NULL];
}


- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([object isEqual:tokenField]){
        NSLog(@"Tokens changed");
    }
}
Run Code Online (Sandbox Code Playgroud)

但只有在我以编程方式更改令牌时才会调用此操作.

如果tokenField更改了令牌,我该如何得到通知?

Pau*_*son 7

NSTokenField行动选择不叫创建一个新的标签的时刻.根据您在Interface Builder中使用的设置,当您按Enter键进行结束编辑(仅在输入发送)或者以其他方式结束编辑时(发送结束编辑),可以调用它.为了获得良好的控制,你需要另一种方法.


标记字符添加到标记字段时出现的蓝色标记称为文本附件(实例NSTextAttachment).在令牌字段中添加/删除标记时,一种计算方法是跟踪令牌字段的基础属性字符串中包含的这些对象数量的更改.

要访问相关的属性字符串,您需要获取fieldEditor layoutManager - 最终提供文本视图中显示的字符串的对象.一旦得到它,每次收到controlTextDidChange:消息时,都要计算其string表示中的文本附件数attributedString.如果此时间的数字大于先前计数中记录的数字,则刚刚添加了标记.

#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (weak) NSLayoutManager *lm;
@property (nonatomic) NSUInteger tokenCount;

@end

@implementation AppDelegate

// The text in the fieldEditor has changed. If the number of attachments in the
// layoutManager's attributedString has changed, either a new tag has been added,
// or an existing tag has been deleted.
-(void)controlTextDidChange:(NSNotification *)obj {
    NSUInteger updatedCount = [self countAttachmentsInAttributedString:self.lm.attributedString];
    if (updatedCount > self.tokenCount) {
        NSLog(@"ADDED");
        self.tokenCount = updatedCount;
    } else if (updatedCount < self.tokenCount) {
        NSLog(@"REMOVED");
        self.tokenCount = updatedCount;
    }
}

// About to start editing - get access to the fieldEditor's layoutManager
-(BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor {
    self.lm = [(NSTextView *)fieldEditor layoutManager];
    return YES;
}

// Iterate through the characters in an attributed string looking for occurrences of
// the NSAttachmentCharacter.
- (NSInteger)countAttachmentsInAttributedString:(NSAttributedString *)attributedString {
    NSString *string = [attributedString string];
    NSUInteger maxIndex = string.length - 1;
    NSUInteger counter = 0;

    for (int i = 0; i < maxIndex + 1; i++) {
        if ([string characterAtIndex:i] == NSAttachmentCharacter) {
            counter++;
        }
    }
    return counter;
}

@end
Run Code Online (Sandbox Code Playgroud)