如何使 NSTokenField 的值绑定提供 NSString?

发布于 2024-07-11 10:39:43 字数 413 浏览 9 评论 0原文

我已将 NSTextField 替换为 NSTokenField,以便我可以执行一些自动完成操作。 NSTextField 的值绑定到控制器类的 NSString 属性。 现在我已将 NSTextField 更改为 NSTokenField,该值已更改为 NSArray

如何使 NSTokenField 值绑定成为 NSString

将值从 NSString 更改为 NSArray 似乎是糟糕的 OO 设计。 我认为子类应该能够替换超类,而不需要对子类进行任何修改。

I have replaced an NSTextField with an NSTokenField so that I can perform some auto-completion. The value of the NSTextField was bound to a NSString attribute of a controller class. Now that I have changed the NSTextField to an NSTokenField the value has changed to an NSArray.

How do I make the NSTokenField value binding be an NSString?

The changing of the value from an NSString to an NSArray seems like bad OO design. I though that a subclass should be able replace a superclass without any modifications to the subclass.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

世界如花海般美丽 2024-07-18 10:39:43

如果您想要的是自动完成,而不是标记化,您可以通过使用普通 NSTextField 并实现委托方法来实现此目的:(

- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index

此方法实际上是在 NSControl,NSTextField 的超类中声明的。)

如果您确实想要标记化,那么您将必须提供一个 NSArray 以便在 token 字段中显示对象值。 如 NSTokenField 编程指南,您提供的数组将是字符串和对象的混合。 字符串将按原样显示,任何非字符串对象将在标记字段中显示为标记。 您需要实现各种 NSTokenField 委托方法来为数组中的每个表示的对象提供要显示的字符串。

看来 Cocoa Bindings Reference 指出绑定到 NSTokenField 值的对象应该是字符串或数字,但根据我的经验,这是不正确的,令牌字段应该绑定到 NSArray,就像使用 setObjectValue 时:

If all you want is autocompletion, and not tokenization, you can achieve this by using a plain NSTextField and implementing the delegate method:

- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index

(This method is actually declared in NSControl, NSTextField's superclass.)

If you do want to have tokenization, then you will have to provide an NSArray for the object value to be displayed in the token field. As explained in the NSTokenField programming guide, the array you provide will be a mix of strings and objects. Strings will be displayed as-is, and any non-string objects will be displayed as tokens in the token field. You would need to implement the various NSTokenField delegate methods to provide a string to be displayed for each represented object in your array.

It does appear that the Cocoa Bindings Reference states that the object bound to the value of an NSTokenField should be a string or number, but in my experience, this is incorrect, and the token field should be bound to an NSArray, just like when using setObjectValue:

谁人与我共长歌 2024-07-18 10:39:43

您可以对自己的 NSValueTransformer 进行子类化并将其设置在您的绑定中。

You can subclass your own NSValueTransformer and set it in your binding.

仙女山的月亮 2024-07-18 10:39:43

NSTokenField 的值绑定接受 NSString 或 NSNumber 绑定,而不是 NSArray。 你如何确定它需要 NSArray?

NSTokenField's value binding accepts an NSString or NSNumber binding, not an NSArray. How have you determined that it is wanting an NSArray?

七分※倦醒 2024-07-18 10:39:43

做到这一点的最好方法(正如 Cocoafan 指出的那样)是使用 价值转换器。 值转换器允许您将模型使用的对象类型转换为适合视图的类型。 这是一个非常简单的字符串/数组转换器,它允许您将数据存储为逗号分隔的字符串,但会将其来回转换为字符串数组。

@interface StringArrayTransformer: NSValueTransformer {}
@end

@implementation StringArrayTransformer

+ (Class)transformedValueClass { return [NSString class]; }

+ (BOOL)allowsReverseTransformation { return YES; }

- (id)transformedValue:(id)value {
    NSString *string = (NSString*) value;
    return [string componentsSeparatedByString:@", "];
}

-(id)reverseTransformedValue:(id)value {
    NSArray *array = (NSArray*)value;
    return [array componentsJoinedByString:@", "];
}
@end

如果您正在为 NSTokenField 使用绑定,那么要使用此转换器,只需在 Interface Builder 中选择 NSTokenField,然后在右侧的 Bindings Inspector 中,对于 Value 绑定,将“Value Transformer”设置为 StringArrayTransformer如下所示。

设置NSTokenField 的值转换器绑定

The best way to do this (as Cocoafan pointed out) is to use Value Transformers. Value transformers allow you convert the object-type used your model into a type that's suitable for a view. Here is a very simple String/Array transformer that allows you to store your data as a comma separated string but will convert it back and forth to an array of strings.

@interface StringArrayTransformer: NSValueTransformer {}
@end

@implementation StringArrayTransformer

+ (Class)transformedValueClass { return [NSString class]; }

+ (BOOL)allowsReverseTransformation { return YES; }

- (id)transformedValue:(id)value {
    NSString *string = (NSString*) value;
    return [string componentsSeparatedByString:@", "];
}

-(id)reverseTransformedValue:(id)value {
    NSArray *array = (NSArray*)value;
    return [array componentsJoinedByString:@", "];
}
@end

If you're using bindings for your NSTokenField then to use this the transformer simply select the NSTokenField in Interface Builder, then in the Bindings Inspector on the right hand side, for the Value binding, set the "Value Transformer" to StringArrayTransformer as per below.

Setting the Value Transformer Binding for NSTokenField

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文