单击后恢复 NSAttributedString 的视觉状态
Restore the visual state of an NSAttributedString after having clicked on it
我需要在点击 NSAttributedString 后恢复它的视觉状态。
我的 NSAttributedString 包含 links 归因于范围。
在这个例子中,文本“@user”有一个 link 到 "htpp://somesite.com/":
let text = "Hey @user!"
let attr = NSMutableAttributedString(string: text)
let range = NSRange(location: 4, length: 5)
attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: range)
attr.addAttribute(NSLinkAttributeName, value: "htpp://somesite.com/", range: range)
let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50))
tf.allowsEditingTextAttributes = true
tf.isSelectable = true
tf.stringValue = text
tf.attributedStringValue = attr
它运行良好:单击文本字段中的“@user”,它会启动 URL。
但是一旦点击,属性颜色就会消失,取而代之的是蓝色,并添加下划线:
我找不到在单击字符串后恢复原始颜色的解决方案(或者完全避免这种自动更改)。
我见过 this and this 但没有实际的解决方案,我无法将指向的库集成到我的项目中(实际上我真的很想不必导入任何库)。
请注意,我现有的代码在 Swift 中,但我可以使用 Objective-C 解决方案。
单击 link 时,字段编辑器会显示文本。字段编辑器中的默认 link 文本样式为蓝色和下划线。
解决方案 1:在 NSTextFieldCell
.
的子类中的 setUpFieldEditorAttributes:
覆盖中更改 link 的文本样式
- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj {
NSText *fieldEditor = [super setUpFieldEditorAttributes:textObj];
if ([fieldEditor isKindOfClass:[NSTextView class]]) {
NSMutableDictionary *linkAttributes = [((NSTextView *)fieldEditor).linkTextAttributes mutableCopy];
linkAttributes[NSForegroundColorAttributeName] = [NSColor orangeColor];
[linkAttributes removeObjectForKey:NSUnderlineStyleAttributeName];
((NSTextView *)fieldEditor).linkTextAttributes = linkAttributes;
}
return fieldEditor;
}
副作用:字段编辑器由 window 中的所有控件共享,所有控件现在将显示橙色 links。
解决方案 2:使用 fieldEditor:forObject:
方法或 NSWindow
的 windowWillReturnFieldEditor:toObject:
委托方法替换您自己的字段编辑器。文本字段有自己的字段编辑器,其他控件不会有橙色 link。不需要 NSTextField
或 NSTextFieldCell
的子类。
示例:(AppDelegate 是 window 的委托)
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textField;
@property (nonatomic, strong) NSTextView *linkFieldEditor;
@end
@implementation AppDelegate
- (NSTextView *)linkFieldEditor {
if (!_linkFieldEditor) {
_linkFieldEditor = [[NSTextView alloc] initWithFrame:NSZeroRect];
_linkFieldEditor.fieldEditor = YES;
NSMutableDictionary *linkAttributes = [_linkFieldEditor.linkTextAttributes mutableCopy];
linkAttributes[NSForegroundColorAttributeName] = [NSColor orangeColor];
[linkAttributes removeObjectForKey:NSUnderlineStyleAttributeName];
_linkFieldEditor.linkTextAttributes = linkAttributes;
}
return _linkFieldEditor;
}
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client {
if (client == self.textField)
return self.linkFieldEditor;
else
return nil;
}
解决方案 3:创建 NSTextFieldCell
的子类,实现 fieldEditorForView:
和 return 您自己的字段编辑器。这类似于解决方案 2,但由单元而不是 window 委托实现。
关于字段编辑器的文档:Text Fields, Text Views, and the Field Editor and Using a Custom Field Editor。
我需要在点击 NSAttributedString 后恢复它的视觉状态。
我的 NSAttributedString 包含 links 归因于范围。
在这个例子中,文本“@user”有一个 link 到 "htpp://somesite.com/":
let text = "Hey @user!"
let attr = NSMutableAttributedString(string: text)
let range = NSRange(location: 4, length: 5)
attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: range)
attr.addAttribute(NSLinkAttributeName, value: "htpp://somesite.com/", range: range)
let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50))
tf.allowsEditingTextAttributes = true
tf.isSelectable = true
tf.stringValue = text
tf.attributedStringValue = attr
它运行良好:单击文本字段中的“@user”,它会启动 URL。
但是一旦点击,属性颜色就会消失,取而代之的是蓝色,并添加下划线:
我找不到在单击字符串后恢复原始颜色的解决方案(或者完全避免这种自动更改)。
我见过 this and this 但没有实际的解决方案,我无法将指向的库集成到我的项目中(实际上我真的很想不必导入任何库)。
请注意,我现有的代码在 Swift 中,但我可以使用 Objective-C 解决方案。
单击 link 时,字段编辑器会显示文本。字段编辑器中的默认 link 文本样式为蓝色和下划线。
解决方案 1:在 NSTextFieldCell
.
setUpFieldEditorAttributes:
覆盖中更改 link 的文本样式
- (NSText *)setUpFieldEditorAttributes:(NSText *)textObj {
NSText *fieldEditor = [super setUpFieldEditorAttributes:textObj];
if ([fieldEditor isKindOfClass:[NSTextView class]]) {
NSMutableDictionary *linkAttributes = [((NSTextView *)fieldEditor).linkTextAttributes mutableCopy];
linkAttributes[NSForegroundColorAttributeName] = [NSColor orangeColor];
[linkAttributes removeObjectForKey:NSUnderlineStyleAttributeName];
((NSTextView *)fieldEditor).linkTextAttributes = linkAttributes;
}
return fieldEditor;
}
副作用:字段编辑器由 window 中的所有控件共享,所有控件现在将显示橙色 links。
解决方案 2:使用 fieldEditor:forObject:
方法或 NSWindow
的 windowWillReturnFieldEditor:toObject:
委托方法替换您自己的字段编辑器。文本字段有自己的字段编辑器,其他控件不会有橙色 link。不需要 NSTextField
或 NSTextFieldCell
的子类。
示例:(AppDelegate 是 window 的委托)
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textField;
@property (nonatomic, strong) NSTextView *linkFieldEditor;
@end
@implementation AppDelegate
- (NSTextView *)linkFieldEditor {
if (!_linkFieldEditor) {
_linkFieldEditor = [[NSTextView alloc] initWithFrame:NSZeroRect];
_linkFieldEditor.fieldEditor = YES;
NSMutableDictionary *linkAttributes = [_linkFieldEditor.linkTextAttributes mutableCopy];
linkAttributes[NSForegroundColorAttributeName] = [NSColor orangeColor];
[linkAttributes removeObjectForKey:NSUnderlineStyleAttributeName];
_linkFieldEditor.linkTextAttributes = linkAttributes;
}
return _linkFieldEditor;
}
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client {
if (client == self.textField)
return self.linkFieldEditor;
else
return nil;
}
解决方案 3:创建 NSTextFieldCell
的子类,实现 fieldEditorForView:
和 return 您自己的字段编辑器。这类似于解决方案 2,但由单元而不是 window 委托实现。
关于字段编辑器的文档:Text Fields, Text Views, and the Field Editor and Using a Custom Field Editor。