Home > Back-end >  `ColorPicker` with active label?
`ColorPicker` with active label?

Time:05-21

Consider the following code:

struct ContentView: View {
    @State var color: Color = .blue
    var body: some View {
        ColorPicker(selection: $color) {
            Label("Pallete", systemImage: "paintpalette")
        }
    }
}

It brings up a color picker modal view if you tap on color circle. I would like the same to happen also for taps on the label.

CodePudding user response:

These is way to use the fancy system color picker any way we like, but as of iOS 15 it will require bringing with UIKit.

Create a new view struct like this:

import SwiftUI

struct ColorPickerPanel: UIViewControllerRepresentable {
    @Binding var color: Color
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    func makeUIViewController(context: Context) -> UIColorPickerViewController {
        let picker = UIColorPickerViewController()
        picker.delegate = context.coordinator
        return picker
    }
    
    func updateUIViewController(_ picker: UIColorPickerViewController, context: Context) {
        picker.selectedColor = UIColor(color)
    }
    
    class Coordinator: NSObject, UIColorPickerViewControllerDelegate {
        var parent: ColorPickerPanel
        
        init(_ pageViewController: ColorPickerPanel) {
            self.parent = pageViewController
        }
        
        func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
            parent.color = Color(uiColor: viewController.selectedColor)
        }
    }
}

Then use it like this:

struct ContentView: View {
    @State var color: Color = .accentColor
    @State var isColorPickerPresented = false
    var body: some View {
        VStack {
            Button {
                isColorPickerPresented = true
            } label: {
                ColorPicker(selection: $color) {
                    Label("Pallete", systemImage: "paintpalette")
                        .allowsHitTesting(true)
                        .accessibilityAddTraits(.isButton)
                }
            }
        }
        .sheet(isPresented: $isColorPickerPresented) {
            ZStack (alignment: .topTrailing) {
                ColorPickerPanel(color: $color)
                Button {
                    isColorPickerPresented = false
                } label: {
                    Image(systemName: "xmark.circle.fill")
                        .foregroundStyle(.tint, .secondary)
                        .font(.title)
                }
                .offset(x: -10, y: 10)
            }
        }
    }
}

You may provide another to dismiss picker, of course.

  • Related