Skip to content

Instantly share code, notes, and snippets.

@Amzd
Last active April 19, 2024 18:42
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Amzd/62160c84a29ae93d565b20f63b9e3247 to your computer and use it in GitHub Desktop.
Save Amzd/62160c84a29ae93d565b20f63b9e3247 to your computer and use it in GitHub Desktop.
What SwiftUI's ColorPicker should have been.
import SwiftUI
@available(iOS 14.0, *)
public struct ColorPickerWithoutLabel: UIViewRepresentable {
@Binding var selection: Color
var supportsAlpha: Bool = true
public init(selection: Binding<Color>, supportsAlpha: Bool = true) {
self._selection = selection
self.supportsAlpha = supportsAlpha
}
public func makeUIView(context: Context) -> UIColorWell {
let well = UIColorWell()
well.supportsAlpha = supportsAlpha
return well
}
public func updateUIView(_ uiView: UIColorWell, context: Context) {
uiView.selectedColor = UIColor(selection)
}
}
extension View {
@available(iOS 14.0, *)
public func colorPickerSheet(isPresented: Binding<Bool>, selection: Binding<Color>, supportsAlpha: Bool = true, title: String? = nil) -> some View {
self.background(ColorPickerSheet(isPresented: isPresented, selection: selection, supportsAlpha: supportsAlpha, title: title))
}
}
@available(iOS 14.0, *)
private struct ColorPickerSheet: UIViewRepresentable {
@Binding var isPresented: Bool
@Binding var selection: Color
var supportsAlpha: Bool
var title: String?
func makeCoordinator() -> Coordinator {
Coordinator(selection: $selection, isPresented: $isPresented)
}
class Coordinator: NSObject, UIColorPickerViewControllerDelegate, UIAdaptivePresentationControllerDelegate {
@Binding var selection: Color
@Binding var isPresented: Bool
var didPresent = false
init(selection: Binding<Color>, isPresented: Binding<Bool>) {
self._selection = selection
self._isPresented = isPresented
}
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
selection = Color(viewController.selectedColor)
}
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
isPresented = false
didPresent = false
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
isPresented = false
didPresent = false
}
}
func getTopViewController(from view: UIView) -> UIViewController? {
guard var top = view.window?.rootViewController else {
return nil
}
while let next = top.presentedViewController {
top = next
}
return top
}
func makeUIView(context: Context) -> UIView {
let view = UIView()
view.isHidden = true
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
if isPresented && !context.coordinator.didPresent {
let modal = UIColorPickerViewController()
modal.selectedColor = UIColor(selection)
modal.supportsAlpha = supportsAlpha
modal.title = title
modal.delegate = context.coordinator
modal.presentationController?.delegate = context.coordinator
let top = getTopViewController(from: uiView)
top?.present(modal, animated: true)
context.coordinator.didPresent = true
}
}
}
@Amzd
Copy link
Author

Amzd commented Oct 27, 2023

@pianostringquartet hmm yea I didnt write this with crossplatform code in mind

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment