macos - 在 NSTokenField 中混合标记和字符串

标签 macos cocoa nstokenfield

我想要一个NSTokenField包含纯文本和标记。这与 this question 中的问题相同。 ,但那里的答案并没有为我解决这个问题。也许我遗漏了一些东西,或者苹果在这些答案发布后的 5 年内改变了一些东西。

具体来说,假设我想输入“hello%tok%”并将其变成这样:

image of text "hello" and token "TOKEN"

为了尝试消除混淆的机会,我总是使用以下类之一的自定义表示对象,而不是纯字符串...

@interface Token : NSObject
@end

@implementation Token
@end


@interface WrappedString : NSObject
@property (retain) NSString* text;
@end

@implementation WrappedString
@end

这是我的委托(delegate)方法:

- (NSString *)tokenField:(NSTokenField *)tokenField
    displayStringForRepresentedObject:(id)representedObject
{
    NSString * displayString = nil;
    if ([representedObject isKindOfClass: [WrappedString class]])
    {
        displayString = ((WrappedString*)representedObject).text;
    }
    else
    {
        displayString = @"TOKEN";
    }
    return displayString;
}

- (NSTokenStyle)tokenField:(NSTokenField *)tokenField
                styleForRepresentedObject:(id)representedObject
{
    NSTokenStyle theStyle = NSPlainTextTokenStyle;
    if ([representedObject isKindOfClass: [Token class]])
    {
        theStyle = NSRoundedTokenStyle;
    }

    return theStyle;
}

- (NSString *)tokenField:(NSTokenField *)tokenField
        editingStringForRepresentedObject:(id)representedObject
{
    NSString * editingString = representedObject;
    if ([representedObject isKindOfClass: [Token class]])
    {
        editingString = nil;
    }
    else
    {
        editingString = ((WrappedString*)representedObject).text;
    }
    return editingString;
}

- (id)tokenField:(NSTokenField *)tokenField
    representedObjectForEditingString:(NSString *)editingString
{
    id repOb = nil;
    if ([editingString isEqualToString:@"tok"])
    {
        repOb = [[[Token alloc] init] autorelease];
    }
    else
    {
        WrappedString* wrapped = [[[WrappedString alloc]
            init] autorelease];
        wrapped.text = editingString;
        repOb = wrapped;
    }
    return repOb;
}

当我输入“hello”时,没有调用任何委托(delegate)方法,这似乎是合理的。当我输入第一个“%”时,有 3 个委托(delegate)调用:

  1. tokenField:representedObjectForEditingString:获取字符串“hello”并将其转换为 WrappedString代表。
  2. tokenField:styleForRepresentedObject:明白了WrappedString并返回NSPlainTextTokenStyle .
  3. tokenField:editingStringForRepresentedObject:得到 WrappedString并返回“hello”。

前两个调用似乎是合理的。我不确定第三个,因为 token 应该是可编辑的,但尚未编辑。我本以为tokenField:displayStringForRepresentedObject:会被调用,但它没有。

当我输入“tok”时,没有调用委托(delegate)方法。当我输入第二个“%”时,tokenField:representedObjectForEditingString:收到字符串“hellotok”,我本来希望只看到“tok”。所以我从来没有机会创建圆形标记。

如果我以其他顺序键入文本“%tok%hello”,那么我确实会得到预期的结果,一个圆形标记,后跟纯“hello”。

顺便说一下,Token Field Programming Guide

Note that there can be only one token per token field that is configured for the plain-text token style.

这似乎意味着不可能自由地混合纯文本和 token 。

最佳答案

我问自己是否在标准应用程序中的任何地方见过混合文本和标记,我确实见过。在系统偏好设置语言和文本面板中的格式选项卡下,单击“自定义...”按钮之一会弹出一个包含标记字段的对话框。这是其中的一部分。

enter image description here

在这里,您不是通过键入标记化字符来创建标记,而是拖放原型(prototype)标记。

要制作一个原型(prototype) token ,请制作另一个 NSTokenField 并将其设置为没有背景或边框,并且可以选择但不可编辑。加载窗口后,您可以使用 objectValue 属性初始化原型(prototype)字段,例如,

self.protoToken.objectValue = @[[[[Token alloc] init] autorelease]];

您需要为每个原型(prototype) token 字段以及可编辑 token 字段设置委托(delegate)。为了能够拖放 token ,您的委托(delegate)必须实现 tokenField:writeRepresentedObjects:toPasteboard:tokenField:readFromPasteboard:

关于macos - 在 NSTokenField 中混合标记和字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38648689/

相关文章:

swift - 在 macOS 应用程序的 Swift 中处理应用程序强制退出

objective-c - 跨线程事件信号(Obj-C)的同步/等待设计?

macos - 如何阻止CFSocket发送回调?

objective-c - NSTokenField 自动完成

cocoa - 单击 NSTokenField 中的 token

c - 安装了 XCode,但 GCC 不起作用

macos - 触控板手势切换到标题/源

cocoa - 无法指定 CTLineDraw 的填充样式

swift - 在 NSTokenField 上获取鼠标点击

linux maven 与 mac maven