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”

至于在弹出窗口中显示不同的值,这里有一个令人费解的概念:

您将把谓词编辑器本地化为英语

有两种方法可以做到这一点

  • 使用.strings文件
  • 使用
    NSDictionary
  • 使用.strings文件

    在您的源代码中,您可以在注释中包含以下内容:

    // 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文件并将该值更改为要显示的值 或 使用工具管理/翻译本地化应用程序
    下面是一个直接在.strings文件中更改内容的示例: 将更改为ist并将书名更改为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标识检查器可以为每个菜单项找到:


    需要注意的是,在上述情况下,您不能更改修饰符,如果更改了
    %[contains]@
    则需要保留所有可能显示的选项。对我来说,要获得每个选项的本地化,我需要将其修改为:
    %[小于、小于或等于、大于、大于或等于、是、不是、包含、以开头、以结尾]@