【问题标题】:Restore the visual state of an NSAttributedString after having clicked on it单击后恢复 NSAttributedString 的视觉状态
【发布时间】:2016-10-03 11:34:42
【问题描述】:

点击后我需要恢复 NSAttributedString 的可视状态。

我的 NSAttributedString 包含归属于范围的链接。

在此示例中,文本“@user”具有指向“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。

但是一旦点击,属性颜色就消失了,取而代之的是这个蓝色并加了下划线:

单击字符串后,我找不到恢复原始颜色的解决方案(或完全避免这种自动更改)。

我见过thisthis,但没有实际的解决方案,我无法将指向的库集成到我的项目中(实际上,我真的很想不必导入任何库)。

请注意,我现有的代码是用 Swift 编写的,但我可以使用 Objective-C 解决方案。

【问题讨论】:

    标签: macos cocoa nsattributedstring nstextfield nstextview


    【解决方案1】:

    单击链接时,文本由字段编辑器显示。字段编辑器中的默认链接文本样式为蓝色并带下划线。

    解决方案 1:在 NSTextFieldCell 的子类中覆盖 setUpFieldEditorAttributes: 更改链接的文本样式。

    - (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;
    }
    

    副作用:字段编辑器由窗口中的所有控件共享,所有控件现在都将显示橙色链接。

    解决方案 2:使用 fieldEditor:forObject: 方法或 NSWindowwindowWillReturnFieldEditor:toObject: 委托方法替换您自己的字段编辑器。文本字段有自己的字段编辑器,其他控件没有橙色链接。不需要 NSTextFieldNSTextFieldCell 的子类。

    示例:(AppDelegate 是窗口的委托)

    @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: 并返回您自己的字段编辑器。这类似于解决方案 2,但由单元而不是窗口委托实现。

    关于字段编辑器的文档:Text Fields, Text Views, and the Field EditorUsing a Custom Field Editor

    【讨论】:

    • 第一个解决方案:非常好。不过,副作用有点问题。有没有办法从那里获取链接本身?我将能够过滤其类型并设置正确的颜色。 // 我不明白你的第二个解决方案,对不起,如果你能解释一下......:p
    • NSTextFieldCell 也有一个属性attributedStringValue
    • 这真的很好,并且提供了多种方法,我喜欢它。非常感谢。
    • 发生了一件非常奇怪的事情:我的问题中的代码不再起作用,即使不点击链接也总是蓝色的,所以我不能再使用你的解决方案了。请看this new question如果你有几分钟,我对此感到非常困惑......
    猜你喜欢
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多