在一个看似微不足道的设置中,我遇到了一个可选的NSTextField和一个NSColorPanel之间不受欢迎的相互作用,我无法摆脱它,这让我抓狂。
这是设置:在一个窗口中,我有一个可选择的多行标签(事实上是一个NSTextField)和一个NSColorWell。
Color Well允许用户在 GUI 中为几何对象着色;它与文本无关。当然,单击颜色井会激活它,即调出共享的NSColorPanel并将颜色井连接到它。
文本字段完全独立于 GUI 中的彩色对象,并向用户呈现数据。它是只读的,即不可编辑。由于数据是按列组织的,因此我使用选项卡进行文本格式设置和NSTextFieldsetAttributedStringValue:
的方法来显示数据。
乍一看,在这样一个微不足道的设置中,一切正常。
但问题来了:我希望用户能够复制文本字段中的数据以在其他地方处理它。因此,NSTextField必须是selectable。将其设置为selectable
问题开始的地方:
当用户单击可选文本字段以选择文本时,窗口的字段编辑器将接管,因此,属性文本的所有选项卡设置都丢失并且文本混合在一起。防止这种情况的常用方法是将NSTextFieldallowsEditingTextAttributes
的属性设置为. 如果我这样做,则在用户选择文本时会保留选项卡格式。但是现在NSColorPanel(如果可见)无意中也切换到文本颜色(始终为黑色),如果颜色池处于活动状态(连接到NSColorPanel),它将保持活动状态,从而将所有几何 GUI 对象的颜色更改为黑色. 哎哟!YES
我发现无法将NSTextFieldselectable
的andallowsEditingTextAttributes
属性设置为但仍然阻止它与NSColorPanel通信。YES
明显的替代方法是保留所选文本的选项卡格式,即使allowsEditingTextAttributes
设置为NO
(这将根据需要断开颜色面板与文本字段的连接)。但是我用这种方法也没有成功,虽然我不太明白为什么:
我的想法是将所需的选项卡设置为defaultParagraphStyle
文本字段的字段编辑器。因此,我设置了一个自定义字段编辑器:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSArray *myTabs = @[
[[NSTextTab alloc] initWithType:NSRightTabStopType location:100],
[[NSTextTab alloc] initWithType:NSRightTabStopType location:200],
[[NSTextTab alloc] initWithType:NSRightTabStopType location:300]
];
NSMutableParagraphStyle *myParagraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[myParagraphStyle setTabStops:myTabs];
myFieldEditor = [NSTextView new]; // myFieldEditor is an instance variable
[myFieldEditor setDefaultParagraphStyle:myParagraphStyle];
[window setDelegate:self];
[window fieldEditor:YES forObject:myTextField];
}
windowWillReturnFieldEditor:toObject:
并为委托方法中的文本字段激活它:
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
{
if (client == myTextField) return myFieldEditor;
return nil;
}
我什至通过子类化我的文本字段的NSTextFieldCell并记录传播的字段编辑器来确保确实使用了我的自定义字段编辑器:
@implementation myTextFieldCell
- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj
{
NSTextView *newTextObj = (NSTextView*)[super setUpFieldEditorAttributes:textObj];
NSLog(@"STYLE: %@", [newTextObj defaultParagraphStyle]);
return newTextObj;
}
@end
现在,当我在文本字段中选择文本时,我得到以下日志输出:
2017-11-02 11:51:07.432 Demo[94807:303] STYLE: Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (
100R,
200R,
300R
), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0.05, HeaderLevel 0
这正是预期的结果。
但是,一旦我选择文本,选项卡格式就会在文本字段中消失。我不知道为什么这不起作用。
所以无论哪种方式,我都被困住了。如果我将NSTextFieldallowsEditingTextAttributes
的属性设置为,则在选择文本时会保留选项卡格式,但我在 GUI 中的彩色对象会无意中变为黑色。如果我将该属性设置为,则颜色面板的行为应如此,但一旦我选择文本,选项卡格式就会丢失。YES
allowsEditingTextAttributes
NO
这是一个非常不幸的案例,Cocoa 试图变得太聪明,从而使完全微不足道的设置成为一个大问题。
有什么想法吗?