Reputation: 465
In Interface Builder I have a non-editable label (NSTextField
). The contents of the label is created using Cocoa Bindings. The value of the binding is an NSAttributedString
(created using a talue transformer). See image:
The value transformer essentially specifies the font for specific characters, as per Markdown formatting (i.e. Italic and Bold). Such that String
--> NSAttributedString
. The label's attributedStringValue
is changed appropriately
When selecting the label in the UI. The font resets to what is specified in IB, and not what was set as the NSAttributedString
. If you don't select the text then everything looks good.
Before clicking on the label:
After clicking/selected the label:
NSTextField
but there's nothing really to override that enables me to disable any font changes when the text is selected.NSTextView
s not NSTextField
sUpvotes: 3
Views: 1388
Reputation: 168
Swift 5 solution
First you need to set this property for your NSTextField
cell.textField?.allowsEditingTextAttributes = true
Then, where you are creating the NSAttributedString, do this first
// Default font and color, to be used where no attritubes are set
let default_font = NSFont(name: "Courier New", size: 14)
let default_color = NSColor.white
let entire_str_range = NSMakeRange(0, text.string.count)
mutable_attr_str.removeAttribute(NSAttributedString.Key.font, range: entire_str_range)
mutable_attr_str.addAttribute(NSAttributedString.Key.font, value: default_font!, range: entire_str_range)
mutable_attr_str.removeAttribute(NSAttributedString.Key.foregroundColor, range: entire_str_range)
mutable_attr_str.addAttribute(NSAttributedString.Key.foregroundColor, value: default_color, range: entire_str_range)
mutable_attr_str.removeAttribute(NSAttributedString.Key(rawValue: "NSOriginalFont"), range: entire_str_range)
mutable_attr_str.addAttribute(NSAttributedString.Key(rawValue: "NSOriginalFont"), value: default_font!, range: entire_str_range)
Then set up your NSAttributedString however you like. When clicked, it should keep your additional attributes, and the parts of the string with no attributes will default to the above font and color.
Upvotes: 0
Reputation: 401
I believe I found the solution to this issue, which seems unsolved based on the original poster's comments above.
I had an NSTextField that was selectable but not editable. The text was set by creating NSAttributedString with font and text color attributes, and passing this to the NSTextField's setAttributedStringValue
method.
The problem as that the line spacing of the text was wrong until I clicked a text field and then clicked a different text field, as shown in the GIF below. Once the clicking was done, the text displayed properly.
Upon examining the text attributes of the NSTextField before and after editing, I noticed that NSOriginalFont was set to .AppleSystemUIFont 12pt instead of my font, which was Helvetica Neue 11pt.
BEFORE
NSFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
NSOriginalFont = "\".AppleSystemUIFont 12.00 pt. P [] (0x600000d8f0f0) fobj=0x10361b1a0, spc=3.39\"";
AFTER:
NSFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
NSOriginalFont = "\"HelveticaNeue 11.00 pt. P [] (0x600000e46400) fobj=0x1040163d0, spc=3.06\"";
I solved the problem by setting the NSAttributedString's font attribute not only NSFontAttributeName (i.e., @"NSFont") but also @"NSOriginalFont".
[controlText removeAttribute:NSFontAttributeName range:(NSMakeRange(0, len))];
[controlText addAttribute:NSFontAttributeName value:font range:(NSMakeRange(0, len))];
[controlText removeAttribute:@"NSOriginalFont" range:(NSMakeRange(0, len))];
[controlText addAttribute:@"NSOriginalFont" value:font range:(NSMakeRange(0, len))];
Upvotes: 2
Reputation: 1180
You need to set allowsEditingTextAttributes = true
For example:
class ViewController: NSViewController {
dynamic var markdownText : String?
@IBOutlet weak var label: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
label.allowsEditingTextAttributes = true
}
}
Then you can select text as in my example:
Here is the code:https://github.com/emankovski/BindingFormattedText
Upvotes: 11