I am trying to replace one color with another in NSAttributedString to enable a dark mode in a pre-Mojave-app. I have a long NSTextView which holds the string.
Is there any way to remap or mutate the color that is already set in the NSTextView, similar to what the Mojave dark mode does with NSColor.textColor? If there are multiple documents open, formatting the string by enumerating through ranges and attributes one by one is very slow.
Hints & tips using Swift or Objective-C are greatly appreciated!
Short Answer: Make your own "adaptable" colors.
Long Answer
Make a subclass of
NSColorwhich has two readonly (to keep with NSColor being immutable) instanceNSColorproperties for the standard and dark colors.Add a class property to get/set which color should be used.
Define your own
init/newmethods which take the underlying standard and dark colors.Add all of
NSColor's creation methods to your colors@interfacemarking them allNS_UNAVAILBLE– this prevents accidental use of them.Override all the methods required – see
NSColor.h(use "Jump to Definition" in Xcode to open it). Each override simply directs the method to the appropriate standard or dark color. This is just a bunch of boilerplate code.Now use your subclass to color your
NSAttributedString. When you wish to switch mode use the class property to switch all the colors on-the-fly and redraw your string.HTH