Objective c NSPredicateEditor&;NSExpression-显示是否可以与谓词的值不同?
我有一个谓词编辑器,模板是通过以下方式生成的:Objective c NSPredicateEditor&;NSExpression-显示是否可以与谓词的值不同?,objective-c,cocoa,nspredicate,nspredicateeditor,nsexpression,Objective C,Cocoa,Nspredicate,Nspredicateeditor,Nsexpression,我有一个谓词编辑器,模板是通过以下方式生成的: NSArray * test = [NSArray arrayWithObjects: [NSExpression expressionForKeyPath: @"Abc"], [NSExpression expressionForKeyPath: @"Def"], nil]; NSPredicat
NSArray * test = [NSArray arrayWithObjects:
[NSExpression expressionForKeyPath: @"Abc"],
[NSExpression expressionForKeyPath: @"Def"],
nil];
NSPredicateEditorRowTemplate * template = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions: test
rightExpressionAttributeType: NSStringAttributeType
modifier: NSDirectPredicateModifier
operators: [NSArray arrayWithObject:
[NSNumber numberWithUnsignedInteger:NSContainsPredicateOperatorType]]
options:(NSCaseInsensitivePredicateOption|NSDiacriticInsensitivePredicateOption)];
因此,如果我像这样填写谓词编辑器:
当我注销生成的谓词时,我得到:
Abc包含[cd]“Abc”或Def包含[cd]“Def”
我想知道的是,我是否可以让谓词编辑器模板显示不同于在生成的谓词中设置的值
例如:我希望输出谓词具有:
Field1包含[cd]“abc”或Field2包含[cd]“def”
即使编辑器仍将
abc
和def
显示为字段。这可能吗?基本上,您希望修改弹出按钮中菜单项的标题。这就是你需要做的。它不应该影响返回的基础谓词。如果您是在interface builder中创建的,则很容易获取模板的菜单项并设置其标题。但既然你是在代码中完成的,你就必须在代码中修复它
下面是你可以怎么做的。在我的行模板类中,我想更改NSTextFields的宽度。所以在我的行模板类中,我查找它们并像这样修改它们
- (void)awakeFromNib {
NSArray* views = [self templateViews];
for (id view in views) {
if ([[view class] isEqual:[NSTextField class]]) {
NSRect tfFrame = [view frame];
tfFrame.size.width = 600;
[view setFrame:tfFrame];
}
}
}
您可以看到,我获取了TemplateView并查找NSTextFields。。。然后修改它们。你可以做一些类似的事情来寻找N按钮。找到一个后,请检查其菜单项标题,查找标题为“abc”和“def”的菜单项,并将其标题分别更改为“Field1”和“Field2”。是的,您可以这样做
您希望左表达式数组成为最终谓词中的实际键路径。在您的情况下,“Field1”
和“Field2”
至于在弹出窗口中显示不同的值,这里有一个令人费解的概念:
您将把谓词编辑器本地化为英语
有两种方法可以做到这一点
NSDictionary
// NSLocalizedStringFromTable(@"%[Field1,Field2]@ %[contains]@ %@", @"PredicateEditor", @"")
在源代码上运行时,将生成一个包含以下项的PredicateEditor.strings
文件:
"%[Field1]@ %[contains]@ %@" = "%[Field1]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Field2]@ %[contains]@ %@";
您可以将值更改为:
"%[Field1]@ %[contains]@ %@" = "%[Abc]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Def]@ %[contains]@ %@";
然后,当您创建nspredicateditor
时,将属性设置为“PredicateEditor”
,编辑器将处理其余部分
使用NSDictionary
这将遵循与.strings选项相同的基本概念,只是您基本上会:
NSDictionary *formatting = @{
@"%[Field1]@ %[contains]@ %@" : @"%[Abc]@ %[contains]@ %@",
@"%[Field2]@ %[contains]@ %@" : @"%[Def]@ %[contains]@ %@"
}
[myPredicateEditor setFormattingDictionary:formatting];
这就是你要做的
我很久以前就知道了,你可能会发现它有更多有用的信息。与其使用
NSLocalizedString
选项特定格式的文本和genstrings
来生成本地化字符串,不如自己生成最终的本地化.strings文件字符串
,我们可以使用专用API\u generateFormattingDictionaryStringsFile
从NSPredicateEditor本身获取格式化字符串:
extension NSPredicateEditor {
func formattingDictionaryStrings() -> String? {
var strings: String? = nil
if let formattingDictionaryData = self.perform(Selector("_generateFormattingDictionaryStringsFile"))?.takeRetainedValue() as? Data {
strings = String(data: formattingDictionaryData, encoding: .utf16)
}
return strings
}
}
这将生成所有排列,跳过对genstring
的需要。然后用用户显示的字符串替换=
右侧的令牌
"%[ABC]@ %[is]@ %[123]@" = "%1$[ABC]@ %2$[is]@ %3$[123]@";
"%[ABC]@ %[is]@ %[456]@" = "%1$[ABC]@ %2$[is]@ %3$[456]@";
"%[ABC]@ %[is]@ %[789]@" = "%1$[ABC]@ %2$[is]@ %3$[789]@";
"%[ABC]@ %[contains]@ %[123]@" = "%1$[ABC]@ %2$[contains]@ %3$[123]@";
"%[ABC]@ %[contains]@ %[456]@" = "%1$[ABC]@ %2$[contains]@ %3$[456]@";
"%[ABC]@ %[contains]@ %[789]@" = "%1$[ABC]@ %2$[contains]@ %3$[789]@";
更好的是,您可以构造代码来构建每个NSPredicateEditorRowTemplate
,将谓词内部使用的键路径和该选项的本地化字符串作为输入
然后,您的方法可以生成上面的字符串,但是已经插入了正确的本地化
注意:调用此\u generateFormattingDictionaryStringsFile
私有API方法似乎会在NSPredicateEditor中导致随机崩溃:
对于键行类型
,此类不符合键值编码
因此,请确保在需要时运行一次,但在您正常运行或测试应用程序时,不要让它处于活动状态。是的,这完全是一个本地化问题,因为对象是菜单项。而且他们很容易被这样对待 你需要做的就是
- 本地化您的应用程序李>
- 然后输入.strings文件并将该值更改为要显示的值 或 使用工具管理/翻译本地化应用程序
/* Class = "NSMenuItem"; title = "is"; ObjectID = "G1c-st-GEK"; */
"G1c-st-GEK.title" = "ist";
/* Class = "NSMenuItem"; title = "booktitle"; ObjectID = "nQh-54-5Nx"; */
"nQh-54-5Nx.title" = "Buchtitel";
备注:查找要更改的行的最佳方法是查找对象ID。UIB标识检查器可以为每个菜单项找到:
需要注意的是,在上述情况下,您不能更改修饰符,如果更改了
%[contains]@
则需要保留所有可能显示的选项。对我来说,要获得每个选项的本地化,我需要将其修改为:%[小于、小于或等于、大于、大于或等于、是、不是、包含、以开头、以结尾]@