如何在调用NSTextField setStringValue后更新扩展工具提示大小:?

时间:2014-02-20 22:21:33

标签: macos tooltip nstextfield appkit

如果视图包含启用了扩展工具提示的NSTextField且文本不适合,则用户将光标悬停在该字段上,OS X显示扩展工具提示。如果您随后致电setStringValue:更改NSTextField的文字内容,则不会更新扩展工具提示的尺寸。例如,如果原始文本长度为100个字符,但新文本只有50个字符长,则将鼠标悬停在新文本上将显示一个扩展工具提示,该工具提示足以容纳包含新文本的100个字符。即使新字符串完全适合NSTextField,这通常也会阻止扩展工具提示出现,这是正确的。

也会出现相反的情况:如果原始字符串符合NSTextField,则不会显示扩展工具提示。如果新字符串不适合NSTextField,则不会出现扩展工具提示,即使它应该。

在内部,NSTextField的{​​{1}}实现了NSTextFieldCell方法NSCell。有些东西(我不确定是什么)只调用一次,似乎缓存了结果。使用expansionFrameWithFrame:inView:设置新字符串不会再次调用此函数。

在调用setStringValue:后在NSTextField上调用setNeedsDisplay并不能解决此问题。

那么如何让AppKit调整扩展工具提示的大小?

2 个答案:

答案 0 :(得分:3)

经过大量的实验,我找到了两种方法来解决这个问题。

非常困难的方法是每次文本更改时删除并重新创建整个NSTextField。这很费力,因为NSTextField不符合NSCopying协议,因此您必须使用NSArchiverNSUnarchiver复制原始NSTextField,即使这样,也不会复制某些属性,例如约束。

简单的方法是隐藏和取消隐藏NSTextField

NSTextField *textField;
{...}
[textField setStringValue:newText];
[textField setHidden:YES];
[textField setHidden:NO];

这使得AppKit在expansionFrameWithFrame:inView:的{​​{1}}上调用NSTextField,这会正确更新扩展工具提示的状态和大小。

答案 1 :(得分:0)

[textField resetCursorRects]似乎也导致expansionFrameWithFrame:inView:上也被调用NSTextFieldCell。仅在macOS 10.14中进行了测试。