SwiftUI - NSFontPanel and Color Picker

177 Views Asked by At

I am trying to get NSFontPanel/NSFontManager to work in a SwiftUI Document Template app. I have the following which is a customize version of one I found on GitHub. This lets me pick the size, face, style, etc.

Interestingly, a color picker is included in the FontPanel. The documentation doesn't seem to say this. Is this something new?

Anyway, I would like to either be able to use the color picker to let the user select a color, or if not I would like to hide the color picker - at is not "critical" to this application. I am using this to allow customization of text in a sidebar, so color is nice, but not necessary. Currently the Font settings are working, but the color selection displays, and let you pick on, but it always returns System Color.

Any help would be appreciated.

NOTE: I didn't include the FontPickerDelegate, it just calls this:

public struct FontPicker: View{

    let labelString: String
    @Binding var font: NSFont
    @State var fontPickerDelegate: FontPickerDelegate?

    public init(_ label: String, selection: Binding<NSFont>) {

        self.labelString = label
        self._font = selection
    }

    let fontManager = NSFontManager.shared
    let fontPanel = NSFontPanel.shared

    @AppStorage("setSidebarFont") var setSidebarFont = "System"
    @AppStorage("setSidebarFontSize") var setSidebarFontSize = 24
    @AppStorage("setSidebarFontColor") var setSidebarFontColor = "gray"

    public var body: some View {

        HStack {

            Text(labelString)

            Button {

                if fontPanel.isVisible {
                    fontPanel.orderOut(nil)
                    return
                }

                self.fontPickerDelegate = FontPickerDelegate(self)
                fontManager.target = self.fontPickerDelegate
                fontManager.action = #selector(fontPickerDelegate?.changeAttributes)

                fontPanel.setPanelFont(self.font, isMultiple: false)
                fontPanel.orderBack(nil)

            }  label:  {

                Text("Font Selection: \(setSidebarFont)")
                    .font(.custom(setSidebarFont, size: CGFloat(setSidebarFontSize)))
            }
        }
    }
    
    func fontSelected() {

        self.font = fontPanel.convert(self.font)
        setSidebarFont = self.font.displayName ?? "System"
        setSidebarFontSize = Int(self.font.pointSize)

        var newAttributes = fontManager.convertAttributes([String : AnyObject]())

        newAttributes["NSForegroundColorAttributeName"] = newAttributes["NSColor"]
        newAttributes["NSUnderlineStyleAttributeName"] = newAttributes["NSUnderline"]
        newAttributes["NSStrikethroughStyleAttributeName"] = newAttributes["NSStrikethrough"]
        newAttributes["NSUnderlineColorAttributeName"] = newAttributes["NSUnderlineColor"]
        newAttributes["NSStrikethroughColorAttributeName"] = newAttributes["NSStrikethroughColor"]

        print("\(newAttributes["NSForegroundColorAttributeName"]!)")
    }
}

Screenshot of panel

0

There are 0 best solutions below