Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 在NSTokenField中混合令牌和字符串_Macos_Cocoa_Nstokenfield - Fatal编程技术网

Macos 在NSTokenField中混合令牌和字符串

Macos 在NSTokenField中混合令牌和字符串,macos,cocoa,nstokenfield,Macos,Cocoa,Nstokenfield,我想要一个同时包含纯文本和令牌的NSTokenField。这和中的问题是一样的,但是那里的答案并没有为我解决它。也许我遗漏了什么,也许苹果在这些答案发布后的5年里改变了什么 具体来说,假设我想输入“hello%tok%”,并将其转换为: 为了避免混淆,我总是使用以下类之一的自定义表示对象,而不是普通字符串 @interface Token : NSObject @end @implementation Token @end @interface WrappedString : NSObj

我想要一个同时包含纯文本和令牌的
NSTokenField
。这和中的问题是一样的,但是那里的答案并没有为我解决它。也许我遗漏了什么,也许苹果在这些答案发布后的5年里改变了什么

具体来说,假设我想输入“hello%tok%”,并将其转换为:

为了避免混淆,我总是使用以下类之一的自定义表示对象,而不是普通字符串

@interface Token : NSObject
@end

@implementation Token
@end


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

@implementation WrappedString
@end
以下是我的委托方法:

- (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”时,没有调用任何委托方法,这似乎是合理的。键入第一个“%”时,有3个委托调用:

  • tokenField:representedObjectForEditingString:
    获取字符串“hello”,并将其转换为
    WrappedString
    表示
  • tokenField:styleForRepresentedObject:
    获取
    WrappedString
    并返回
    NSPlainTextTokenStyle
  • tokenField:editingStringForRepresentedObject:
    获取
    WrappedString
    并返回“hello”
  • 前两个电话似乎是合理的。我不确定数字3,因为令牌应该是可编辑的,但它还没有被编辑。我本以为会调用
    tokenField:displayStringForRepresentedObject:
    ,但事实并非如此

    当我输入“tok”时,不会调用委托方法。当我键入第二个“%”时,
    tokenField:representedObjectForEditingString:
    接收字符串“hellotok”,在这里我只希望看到“tok”。因此,我从来没有机会创建舍入令牌

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

    顺便说一句,专家说

    请注意,为纯文本令牌样式配置的每个令牌字段只能有一个令牌


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

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

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

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

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

    您需要为每个原型令牌字段以及可编辑令牌字段设置一个代理。为了能够拖放令牌,您的代表必须实现
    tokenField:writeRepresentedObjects:toPasteboard:
    tokenField:readFromPasteboard:

    我认为苹果改变了一些东西,NSPlainTextTokenStyle不再工作。我不知道这是一个bug还是一个特性。旧的(2015)示例代码使用NSPLAINTEXTOKENSTYLE,但它也有同样的问题,我无法再下载该示例。