我想要一个同时包含纯文本和标记的NSTokenField
。这与this question中的问题相同,但那里的答案尚未为我解决。自发布这些答案以来的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”。
顺便说一句,Token Field Programming Guide说
请注意,为纯文本令牌样式配置的每个令牌字段只能有一个令牌。
这似乎暗示着不可能自由混合纯文本和标记。
最佳答案
我问自己,我是否在标准应用程序中的任何地方看到过混合的文本和令牌,就知道了。在“系统偏好设置”的“语言和文本”面板中,在“格式”选项卡下,单击“自定义...”按钮之一,将弹出一个包含令牌字段的对话框。这是其中一部分。
在这里,您不必通过键入标记化字符来创建标记,而是拖放原型标记。
要制作其中一个原型标记,请制作另一个NSTokenField
并将其设置为没有背景或边框,并且可以选择但不能编辑。加载窗口后,您可以使用objectValue
属性初始化原型字段,例如,
self.protoToken.objectValue = @[[[[Token alloc] init] autorelease]];
您需要为每个原型令牌字段以及可编辑令牌字段设置一个委托。为了能够拖放令牌,您的委托人必须实现
tokenField:writeRepresentedObjects:toPasteboard:
和tokenField:readFromPasteboard:
。关于macos - 在NSTokenField中混合 token 和字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38648689/