Fix photo picker selection tint on iOS 26

On iOS 26 the picker's remote process samples the window's tint color when it connects, ignoring the view-level override, which left the selection badges white on grey in dark mode. Temporarily override the window tint while the picker is presented and restore it when picking finishes or the picker is dismantled.
This commit is contained in:
Ghazi Tozri
2026-09-01 11:15:28 +02:00
committed by Mauro
parent eec2facab1
commit fadd19d847
@@ -50,9 +50,19 @@ struct PhotoLibraryPicker: UIViewControllerRepresentable {
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
// Override the app wide tint color (currently set to `.compound.texActionPrimary
// Override the app wide tint color (currently set to `.compound.texActionPrimary`)
// as it's not legible enough in dark mode
uiViewController.view.tintColor = .compound.textActionAccent
// On iOS 26 the picker reads the window's tint instead so we need
// to make this workaround to override the window tint
DispatchQueue.main.async { [coordinator = context.coordinator] in
coordinator.overrideWindowTint(of: uiViewController)
}
}
static func dismantleUIViewController(_ uiViewController: PHPickerViewController, coordinator: Coordinator) {
coordinator.restoreWindowTint()
}
func makeCoordinator() -> Coordinator {
@@ -62,15 +72,32 @@ struct PhotoLibraryPicker: UIViewControllerRepresentable {
final class Coordinator: NSObject, PHPickerViewControllerDelegate {
private var photoLibraryPicker: PhotoLibraryPicker
private weak var overriddenWindow: UIWindow?
private var originalWindowTint: UIColor?
init(_ photoLibraryPicker: PhotoLibraryPicker) {
self.photoLibraryPicker = photoLibraryPicker
}
func overrideWindowTint(of pickerViewController: PHPickerViewController) {
guard overriddenWindow == nil, let window = pickerViewController.view.window else { return }
overriddenWindow = window
originalWindowTint = window.tintColor
window.tintColor = .compound.textActionAccent
}
func restoreWindowTint() {
overriddenWindow?.tintColor = originalWindowTint
overriddenWindow = nil
}
// MARK: PHPickerViewControllerDelegate
private static let loadingIndicatorIdentifier = "\(PhotoLibraryPicker.self)-Loading"
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
restoreWindowTint()
guard !results.isEmpty else {
photoLibraryPicker.callback(.cancel)
return