Part 10 Finishing the Color Picker | Create the Color Picker with SwiftUI

This article is part of a series focused on creating color picker in SwiftUI. Previously, we completed the color picker itself. This article concludes the series by demonstrating the color picker in a sample application.

TOC

What we make

Display the “Hello World” label and button and the color picker when the button is tapped. Changing the color of the color picker will change the text color of the Hello World label to the color of the color picker.

Implement the model

Create a model class for the sample application.

Implement the ColorPickerAppModel

This sample application manages text color. We created the following model class.

import SwiftUI

class ColorPickerAppModel : ObservableObject {
    @Published var textColor: Color = .black
}

Make it an EnvironmentObject

It is appropriate for the ColorPickerAppModel class to manage information about the app and for its instance to be accessible by the entire app. Hence, such an object is an EnvironmentObject in SwiftUI.

import SwiftUI

@main
struct ColorPickerApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(ColorPickerAppModel())
        }
    }
}

Implement the main screen

Implement the main screen. The main screen features a “Hello World” label and button that triggers the color picker.

Placement of label

The label text is larger, and ColorPickerAppModel.textColor is set to the text color. ColorPickerAppModel is an EnvironmentObject, so you can access it with @EnvironmentObject. If you define a property with @EnvironmentObject, you can access the instance set by the environmentObject() modifier.

The instance set to EnvironmentObject in ColorPickerApp.swift is used when the app is running. However, in Xcode’s Live Preview, the instance passed to environmentObject() running in ContentView_Previews.previews is used. Note the difference.

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(ColorPickerAppModel())
    }
}

Show Color Picker

We develop a function that changes the text color using the previously implemented color picker.

Managing the display state of the color picker

Add code to display the color picker, designed to manage the state of being displayed in SwiftUI. Add a property to ContentView that manages the state of the displayed color picker.

The concept of “managing the displayed state” is a feature that differs greatly from UIKit.

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false

Display the Color Picker

To display the color picker, change the isColorPickerPresented property, which manages the display state, to true. Then, use the sheet modifier to display the modal based on it. sheet modifier displays the ColorPicker.

Also, a ColorPickerModel is needed to initialize the ColorPicker. I think it would be wrong to add it to ColorPickerAppModel, since it is only needed where the color picker is displayed. So, add the property to ContentView.

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false
    @StateObject var colorPickerModel: ColorPickerModel = ColorPickerModel()
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                self.isColorPickerPresented = true
            }
            .sheet(isPresented: $isColorPickerPresented) {
                ColorPicker(model: colorPickerModel)
            }
        }
    }
}

Update ColorPickerAppModel.textColor

Implement the process of assigning the color set in the color picker to ColorPickerAppModel.textColor. When the color picker is closed, the value in the ColorPickerAppModel property is retrieved, and the textColor property is updated. To perform some processing when it is closed, use the onDisappear modifier.

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false
    @StateObject var colorPickerModel: ColorPickerModel = ColorPickerModel()
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                self.isColorPickerPresented = true
            }
            .sheet(isPresented: $isColorPickerPresented) {
                ColorPicker(model: colorPickerModel)
                    .onDisappear() {
                        self.model.textColor = Color(red: self.colorPickerModel.red, green: self.colorPickerModel.green, blue: self.colorPickerModel.blue)
                    }
            }
        }
    }
}
ContentView preview showing the color picker.
ContentView preview showing the color picker

Download the code

Click here to download the code created for this article.

Authored Books

Let's share this post !

Author of this article

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

TOC