简体   繁体   English

更改Cocoa绑定中的空占位符?

[英]Change the null placeholder in a Cocoa binding?

Is there a way to change (for the purpose of localization) the null placeholder in a binding in Cocoa? 有没有办法在Cocoa的绑定中更改(出于本地化的目的)空占位符?

The bindings are set up in Interface Builder for a popup button. 绑定在Interface Builder中设置为弹出按钮。 The two-way nature of the bindings as set up in IB is needed, so doing it programmatically is not really appealing. 需要在IB中设置的绑定的双向性质,因此以编程方式执行它并不是真正吸引人的。

I am aware that the standard way of handling localizations of a nib file is by making one for each language, but since this is the only difference in the whole nib file between the language versions, it seems a bit excessive for a single string. 我知道处理nib文件本地化的标准方法是为每种语言创建一个,但由于这是语言版本之间整个nib文件的唯一区别,对于单个字符串来说似乎有点过分。

If there is a way to modify a binding created in IB, I was thinking about doing it in the file's owner's awakeFromNib method. 如果有办法修改在IB中创建的绑定,我正在考虑在文件的所有者的awakeFromNib方法中执行它。

In the controller object to which you bind, such as your NSDocument class, override -bind:toObject:withKeyPath:options: . 在绑定到的控制器对象(例如NSDocument类)中,覆盖-bind:toObject:withKeyPath:options: . This needs to be the target of that method invocation – the object you select under Bind to: in the nib. 这需要成为该方法调用的目标 - 您在nib中选择Bind to:下的对象。

If you bind to an NSObjectController or NSArrayController, you'll need a subclass. 如果绑定到NSObjectController或NSArrayController,则需要一个子类。

That method should rewrite the options dictionary and invoke super, replacing the value for NSNullPlaceholderBindingOption with your localized string. 该方法应该重写options字典并调用super,用您的本地化字符串替换NSNullPlaceholderBindingOption的值。

I would omit the null placeholder from the nib and that key value in code, though you could of course take the passed-in value for that key and translate it, instead. 我会省略nib中的null占位符和代码中的键值,尽管你当然可以获取该键的传入值并转换它。

The other answer no longer seems to work so I've come up with a slightly different solution which modifies an existing binding to use the given null placeholder string: 另一个答案似乎不再起作用,所以我想出了一个稍微不同的解决方案,修改现有绑定以使用给定的空占位符字符串:

I have this method in my view controller: 我在视图控制器中有这个方法:

- (void)rebind:(NSString *)binding of:(id)object withNullPlaceholder:(NSString *)nullPlaceholder {
    // Possibly a bad idea, but Xcode doesn't localize the null placeholder so we have do it manually.
    NSDictionary *bindingInfo = [object infoForBinding:binding];

    id bindObject = bindingInfo[NSObservedObjectKey];
    NSString *keyPath = bindingInfo[NSObservedKeyPathKey];
    NSMutableDictionary *options = [bindingInfo[NSOptionsKey] mutableCopy];
    options[NSNullPlaceholderBindingOption] = nullPlaceholder;

    [object unbind:binding];
    [object bind:binding toObject:bindObject withKeyPath:keyPath options:options];
}

I call this in awakeFromNib for all the bindings that need it and pass in a localized string: 我在awakeFromNib调用了所有需要它的绑定并传入一个本地化的字符串:

- (void)awakeFromNib {
    // Hacky hack hack: Xcode is stupid and doesn't localize the null placeholders so we have to do it.
    [self rebind:@"contentValues" of:self.fooPopup withNullPlaceholder:NSLocalizedString(@"No foos available", @"foo popup null placeholder")];
    [self rebind:@"contentValues" of:self.barPopup withNullPlaceholder:NSLocalizedString(@"No bars available", @"bar popup null placeholder")];
}

The localized strings are then localized normally as part of the Localizable.strings file. 然后,本地化字符串通常作为Localizable.strings文件的一部分进行Localizable.strings

I was able to change the null placeholder string (ie "No Value") in a NSPopUpButton that uses bindings. 我能够在使用绑定的NSPopUpButton中更改空占位符字符串(即“无值”)。

Specifically, I wanted to have an popup button menu item that had a title other than "No Value" with a represented object of nil . 具体来说,我希望有一个弹出按钮菜单项,其标题不是“无值”,表示对象nil An empty NSString or nil should be saved in the user defaults when the null placeholder menu item is selected. 选择空占位符菜单项时,应在用户默认值中保存空NSStringnil

NSPopUpButton Bindings: NSPopUpButton绑定:

  • Content is bound to an NSArrayController.arrangedObjects 内容绑定到NSArrayController.arrangedObjects

  • Content Objects is bound NSArrayController.arrangedObjects.exampleContentObject ( NSString ), this is the object that the menu item represents and is the Selected Object , 内容对象绑定NSArrayController.arrangedObjects.exampleContentObjectNSString ),这是菜单项表示的Selected Object ,是Selected Object

  • Content Values is bound to NSArrayController.arrangedObjects.exampleContentValue ( NSString ), this is the title shown in the popup button's menu item. 内容值绑定到NSArrayController.arrangedObjects.exampleContentValueNSString ),这是弹出按钮的菜单项中显示的标题。

  • Selected Object of the popup button is bound to NSSharedUserDefaultsController.values.ExampleUserDefaultsKey which is the same object type as the Content Objects and Selected Object ( NSString ). 弹出按钮的Selected Object绑定到NSSharedUserDefaultsController.values.ExampleUserDefaultsKey ,它与Content ObjectsSelected ObjectNSString )的对象类型相同。 This object should match the object type of the NSUserDefault's key specified in the binding. 此对象应与绑定中指定的NSUserDefault密钥的对象类型匹配。 When an item from the popup button is selected, it will save the Selected Object to the user defaults. 当选择弹出按钮中的项目时,它会将选定对象保存为用户默认值。

To change the null placeholder string from "No Value" to something else, subclass NSPopUpButton and override -[NSPopUpButton bind:toObject:withKeyPath:options:] . 要将空占位符字符串从“无值”更改为其他内容,请NSPopUpButton并覆盖-[NSPopUpButton bind:toObject:withKeyPath:options:]


@interface CustomPopUpButton : NSPopUpButton
@end

@implementation CustomPopUpButton
- (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary<NSString *,id> *)options {
    NSMutableDictionary *mutableOptions = options ? [options mutableCopy] : [NSMutableDictionary dictionaryWithCapacity:1];
    mutableOptions[NSInsertsNullPlaceholderBindingOption] = @YES;
    mutableOptions[NSNullPlaceholderBindingOption] = @"Custom Null Placeholder Text";
    [super bind:binding toObject:observable withKeyPath:keyPath options:[mutableOptions copy]];
}
@end

Finally, select the NSPopUpButton in Interface Builder and under Custom Class in the Xcode Identity Inspector to your the class to the NSPopUpButton subclass. 最后,在Interface Builder中选择NSPopUpButton ,在Xcode Identity Inspector中的Custom Class下选择NSPopUpButton子类中的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM