我有一个谓语编辑器,它的模板通过以下产生:
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 CONTAINS[cd] "abc" OR Def CONTAINS[cd] "def"
我想知道是,如果我能以某种方式有谓语编辑模板显示比获取生成的谓词设置的值不同。
EX:我想输出谓词有:
Field1 CONTAINS[cd] "abc" OR Field2 CONTAINS[cd] "def"
尽管编辑器仍显示abc
和def
的领域。 这可能吗?
是的,你可以做到这一点。
你想表达左侧的阵列是在最后的谓词的实际keyPaths。 在你的情况, "Field1"
和"Field2"
。
作为用于制作不同的值出现在弹出窗口中,这里的地方一个令人费解的概念来自于:
你要本地化谓词编辑成英文 。
有两种方法可以做到这一点。
- 随着.strings文件
- 随着
NSDictionary
随着.strings文件
在你的源代码,你将包括在评论如下:
// NSLocalizedStringFromTable(@"%[Field1,Field2]@ %[contains]@ %@", @"PredicateEditor", @"")
当您运行genstrings
你的源代码,这将产生一个PredicateEditor.strings
带有以下各项文件:
"%[Field1]@ %[contains]@ %@" = "%[Field1]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Field2]@ %[contains]@ %@";
你会改变这些值是:
"%[Field1]@ %[contains]@ %@" = "%[Abc]@ %[contains]@ %@";
"%[Field2]@ %[contains]@ %@" = "%[Def]@ %[contains]@ %@";
然后,当您创建NSPredicateEditor
,您将设置formattingStringsFileName
属性"PredicateEditor"
,编辑器将完成剩下的工作。
随着NSDictionary
这将遵循与.strings选项相同的基本概念,除非你将基本上做到:
NSDictionary *formatting = @{
@"%[Field1]@ %[contains]@ %@" : @"%[Abc]@ %[contains]@ %@",
@"%[Field2]@ %[contains]@ %@" : @"%[Def]@ %[contains]@ %@"
}
[myPredicateEditor setFormattingDictionary:formatting];
这就是你必须做的。
我的博客上讲述这个很久以前,这有可能对您有用的信息。
基本上你要修改的菜单项的标题在您的弹出按钮。 这就是所有你需要做的。 它不应该影响你得到返回的潜在的上游。 如果您在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];
}
}
}
你可以看到,我得到的templateViews并寻找NSTextFields ......然后对其进行修改。 你可以做类似的寻找NSPopupButtons东西。 一旦你找到了一个检查他们的菜单项目名称及查找标题为“ABC”和“DEF”的那些分别改变他们的标题“字段1”和“字段2”。
而不是使用NSLocalizedString
在特定格式的选项文字和genstrings
生成本地化字符串,它似乎更容易/清洁自己生成最终的定位.strings文件中的字符串。
从这个博客中 ,我们可以使用私有API _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
}
}
这将生成所有排列的,跳跃的需要genstrings
。 然后,替换标记到右侧=
您的用户显示的字符串。
"%[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
采取作为输入无论是在谓语内部使用的keyPath和该选项的本地化字符串。
然后,您的方法能产生琴弦之上,但用正确的定位已经插入。
注意:调用此_generateFormattingDictionaryStringsFile
私有API方法似乎引起NSPredicateEditor内随机崩溃:
这个类不是键值编码兼容的关键rowType
。
所以一定需要时运行一次,但不要将其活性,当你正常运行或测试您的应用程序。
是的,这是本地化的所有问题,这要归功于一个事实,即对象是菜单项。 他们可以很容易地对待。
所有你需要做的是...
- 本地化应用程序。
- 然后输入.strings文件和值更改为您要显示或...使用工具来管理/翻译本地化的应用程序是什么。
这里是一个.strings文件中直接改变事物的例子:变化是 北京时间并BOOKTITLE到Buchtitel
/* 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身份检查发现:
文章来源: NSPredicateEditor & NSExpression - Can the display be different than the value for the predicate?