我实现了一个NSTokenField,它使用一些自定义数据对象来显示动态数据。Delegate设置良好,并显示正确的令牌值。
我还在令牌上实现了一个菜单,它允许选择用于显示每个令牌的格式。然而,我的问题是,我无法使NSTokenField立即响应这些更改,并用新选择的格式重新绘制令牌。
如果我在NSTokenField之外点击,它会退出第一个响应程序,它会立即重新绘制。我还可以通过显式地将第一个响应程序设置为nil来通过编程实现这一点。唯一的问题是NSTokenField失去了焦点,并将其重新分配为第一响应者,从而选择字段中的所有内容,因此用户可能会意外地覆盖整个内容。
所以我的问题是,是否有任何方法可以在不改变焦点和选择的情况下触发NSTokenField重新绘制其内容?
我遇到了同样的问题,发现唯一可行的解决方案是在每次内容更改时"重置"令牌字段。基本上,这归结为运行视图控制器的以下方法,该方法处理带有令牌字段的视图:
- (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];
}
所表示的对象是保存正在显示的所有令牌的对象。在我的例子中,那是一大块richt文本,其中的标记基本上是标签。
我发现NSTokenField
是一个令人头疼的问题,但我坚持了下来,因为我很喜欢它的表现。
EDIT:我的令牌字段已绑定到视图控制器的代表对象的tagsAsArray
方法。所以基本上我使用了Cocoa绑定来解决这个问题。
事实证明,您应该在NSTokenField使用的NSTextView对象上调用setNeedsDisplay,而不是在NSToken Field本身上调用setNeedsDisplay。因此,以下代码起作用:(用PyObjC编写)
text_view = token_field.cell().fieldEditorForView_(token_field)
text_view.setNeedsDisplay_(YES)