malcommac / SwiftRichString

👩‍🎨 Elegant Attributed String composition in Swift sauce
MIT License
3.13k stars 211 forks source link

Interface Builder support for macOS #82

Open Maschina opened 5 years ago

Maschina commented 5 years ago

Is there any possibility to implement Interface Builder support for macOS or NSTextField?

Maschina commented 5 years ago

I have made a first try by adding the following to the UIKit+Extras.swift:

elseif os(macOS)

import Cocoa

internal enum IBInterfaceKeys: String {
    case styleName = "SwiftRichString.StyleName"
    case styleObj = "SwiftRichString.StyleObj"
}

extension NSTextField {

    /// The name of a style in the global `NamedStyles` registry.
    @IBInspectable
    public var styleName: String? {
        get { return getAssociatedValue(key: IBInterfaceKeys.styleName.rawValue, object: self) }
        set {
            set(associatedValue: newValue, key: IBInterfaceKeys.styleName.rawValue, object: self)
            self.style = StylesManager.shared[newValue]
        }
    }

    /// Style instance to apply. Any change of this value reload the current text of the control with set style.
    public var style: StyleProtocol? {
        set {
            set(associatedValue: newValue, key: IBInterfaceKeys.styleObj.rawValue, object: self)
            self.styledText = self.stringValue
        }
        get {
            if let innerValue: StyleProtocol? = getAssociatedValue(key: IBInterfaceKeys.styleObj.rawValue, object: self) {
                return innerValue
            }
            return StylesManager.shared[self.styleName]
        }
    }

    /// Use this to render automatically the text with the currently set style instance or styleName.
    public var styledText: String? {
        get {
            return attributedStringValue.string
        }
        set {
            guard let text = newValue else { return }
            let style = self.style ?? Style()
            self.attributedStringValue = style.set(to: text, range: nil)
        }
    }

}

#endif

It shows the property in the IB of course, but this implementation will not have any effect on the final styling in the Interface Builder.

Any ideas?