4

I have a controller with a PKCanvasView that's connected to the window shared PKToolPicker.

I can force the PKToolPicker to have a dark appearance (image 1) with:

if let window = self.parent?.view.window, let toolPicker = PKToolPicker.shared(for: window) {
    toolPicker.overrideUserInterfaceStyle = .dark
}

Unfortunately if the user tap on the color picker button the color picker is not inherit the style and the picker is displayed with a light style (image 2).

Does anyone know how to force PKToolPicker's color picker to have a dark style on iOS 14?

Thank you

enter image description here

DaleOne
  • 233
  • 1
  • 8

2 Answers2

1

Not an easy one. Haven't found a good way to do so, other than changing the interface style for the entire system-wide extras. Mostly, I set it up in the mode I want when I create the interface, and I set it back when it is dismissed. If other peeps have a better solution, I'm all ears.

My code is in SwiftUI, so you might need adapting. I want the light mode on my side, but that's equivalent.

fileprivate static var currentWindowScene: UIWindowScene? {
    UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
}

// Make sur the color picker is not inverted
if let windows = Self.currentWindowScene?.windows {
    for window in windows {
        if window.windowLevel != .normal && window.windowLevel != .alert && window.windowLevel != .statusBar {
            if overriddenWindows[window] == nil {
                DispatchQueue.main.async {
                    overriddenWindows[window] = window.overrideUserInterfaceStyle
                }
            }
            window.overrideUserInterfaceStyle = .light
        }
    }
}

Elsewhere (on toolPicker first initialization):

toolPicker.overrideUserInterfaceStyle = .light

When the window is closed:

.onDisappear {
    if let windows = Self.currentWindowScene?.windows {
        for window in windows {
            if let overridden = overriddenWindows[window] {
                window.overrideUserInterfaceStyle = overridden
            }
        }
        overriddenWindows = .init()
    }
}

When the image is drawn:

var result: UIImage?
UITraitCollection(userInterfaceStyle: UIUserInterfaceStyle.light).performAsCurrent {
result = drawing.image(from: CGRect(x: 0, y: 0,
                                    width:zoneSize.width,
                                    height: zoneSize.height),
                       scale: UIScreen.main.scale)
}
return result
Michel Donais
  • 474
  • 4
  • 13
0

While changing the window.overrideUserInterfaceStyle works, there's a simpler solution: set the color picker's colorUserInterfaceStyle to light: (Obj-C)

toolpicker.colorUserInterfaceStyle = UIUserInterfaceStyleLight;
Gerrit Beuze
  • 903
  • 2
  • 10
  • 26
  • The purpose of the colorUserInterfaceStyle attribute is to override the color palette of the color picker (e.g. black is black in light mode but white in dark mode), not the style of the picker itself. – DaleOne Oct 19 '21 at 22:12