以编程方式更改内容后更新NSTokenField

时间:2012-02-29 23:43:35

标签: cocoa nstokenfield

我已经实现了一个NSTokenField,它使用一些自定义数据对象来显示动态数据。委托设置正常并显示令牌的正确值。

我还在令牌上实现了一个菜单,允许选择用于显示每个令牌的格式。但问题是,我无法让NSTokenField立即响应这些更改并使用新选择的格式重绘令牌。

如果我在NSTokenField外部点击,那么它会重新响应第一个响应者,它会立即重绘。我也可以通过明确地将第一响应者设置为nil来以编程方式执行此操作。唯一的问题是NSTokenField失去焦点 - 并在第一响应者选择字段中的所有内容时重新分配它,以便用户可能意外覆盖整个内容。

所以我的问题是,是否有任何方法只是触发NSTokenField重绘其内容而不改变焦点和选择?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,发现唯一可行的解​​决方案是每次更改内容时“重置”令牌字段。基本上,这归结为运行视图控制器的以下方法,该方法使用令牌字段处理视图:

- (void) resetTokenField {

    // Force the token field to redraw itself by resetting the represented object.

    id anObject = [self representedObject];
    [self setRepresentedObject: nil];
    [self setRepresentedObject: anObject];
    [[self tokenField] setNeedsDisplay: YES];

}

表示的对象是包含正在显示的所有标记的对象。在我的情况下,这是一大堆富文本,其中标记基本上是标记。

我发现NSTokenField是颈部的皇家痛苦,但坚持不懈,因为我非常喜欢它的表现方面。

编辑:我的令牌字段绑定到视图控制器的表示对象的tagsAsArray方法。所以基本上我使用Cocoa绑定来解决问题。

答案 1 :(得分:-1)

It turns out that you are supposed to call setNeedsDisplay on the NSTextView object used by the NSTokenField, instead of calling setNeedsDisplay on the NSTokenField itself. Thus the following code works: (Written in PyObjC)

text_view = token_field.cell().fieldEditorForView_(token_field)
text_view.setNeedsDisplay_(YES)