-2

I have a CFMutableAttributedString set with attributes of key kCTForegroundColorAttributeName and value of type CGColor.

let attrString = NSMutableAttributedString(string: "foo bar")
let range = CFRange(location:0, length:6)
CFAttributedStringSetAttribute(attrString, range, kCTForegroundColorAttributeName, CGColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0))

I'm setting this String on NSTextStorage of NSTextView and none of the colors show.

However, for the same string doing this works -

// attrString is of type CFMutableAttributedString
let ret = NSMutableAttributedString(attributedString: attrString)
ret.addAttribute(.foregroundColor, value: NSColor.red, range: NSMakeRange(0, 10))

Why are attribute using Core Foundation attribute names not working? What would be an efficient way to set the foreground color using core foundation API that would work with NSTextView.

I'm using Swift 5 and OSX 10.15.2.

system64
  • 909
  • 1
  • 11
  • 27
  • 1
    There's no way to tell unless you share the code creating `CFMutableAttributedString` ... – zrzka Jun 22 '20 at 06:20
  • `kCTForegroundColorAttributeName` is `"CTForegroundColor"` and `NSForegroundColorAttributeName` is `"NSColor"`. Have you tried `.foregroundColor` and `NSColor.red` in the `CFMutableAttributedString`? – Willeke Jun 22 '20 at 09:14
  • No need to try it, it works, see [`CFMutableAttributedString`](https://developer.apple.com/documentation/corefoundation/cfmutableattributedstring-rqp): _See the attribute constants in NSAttributedString Application Kit Additions Reference for standard attribute names in macOS..._. `kCT` is a constant from the Core Text framework. – zrzka Jun 22 '20 at 11:39
  • I updated the example with a call to `CFAttributedStringSetAttribute ` on NSMutableAttributedString that doesn't work. – system64 Jun 23 '20 at 08:03
  • Did you read my previous comment and the linked documentation? It says that you have to use `NSAttributedString` AppKit addition reference for attribute names in macOS = you have to use `NSForegroundColorAttributeName` with `CFMutableAttributedString`. `kCT` prefix is the CoreText framework constant, **NOT** the CoreFoundation framework. – zrzka Jun 23 '20 at 14:02

1 Answers1

0

Why are attribute using Core Foundation attribute names not working?

kCTForegroundColorAttributeName is NOT a Core Foundation attribute name. It's a Core Text attribute name and the actual value is CTForegroundColor.

CFMutableAttributedString documentation clearly states:

Attributes are identified by key/value pairs stored in CFDictionary objects. Keys must be CFString objects, while the corresponding values are CFType objects of an appropriate type. See the attribute constants in NSAttributedString Application Kit Additions Reference for standard attribute names in macOS and NSAttributedString UIKit Additions Reference on iOS.

You have to use AppKit framework constants here. The correct one is NSAttributedString.Key.foregroundColor (actual value is NSColor != CTForegroundColor).

enter image description here

let attrString = NSMutableAttributedString(string: "Hallo CoreFoundation!")
let range = CFRange(location: 6, length:14)
CFAttributedStringSetAttribute(attrString,
                               range,
                               NSAttributedString.Key.foregroundColor as CFString,
                               NSColor.red);

label.attributedStringValue = attrString
zrzka
  • 20,249
  • 5
  • 47
  • 73