In this demo, you’ll learn how to declare custom views and how to design views that can be reused in many places of your app.
Open ContentView.swift, compile, and run the project. You can also run Xcode Previews by using the shortcut CMD+Option+P
.
RGB Picker has three sliders where users can choose the amount of red, green, and blue they want and tap “Set Color” to set that color to the rectangle at the top.
Notice that all three sliders are very similar. They all have a label at the top, and they have a slider with the tint color they set. The code to set up the three sliders is identical as well — a VStack
, a Text
, and a Slider
. With the exception of the string in the texts and the binding in the sliders, this code is identical.
VStack {
VStack(spacing: 0) {
Text("Red")
Slider(value: $red, in: 0...255)
.tint(.red)
}
VStack(spacing: 0) {
Text("Green")
Slider(value: $green, in: 0...255)
.tint(.green)
}
VStack(spacing: 0) {
Text("Blue")
Slider(value: $blue, in: 0...255)
.tint(.blue)
}
}
This code duplication is not good. You’ll refactor that now.
Start by defining the model of your slider view. In Xcode, create a new Swift file and name it RGBSlider.swift.
Next, add the following code:
enum RGBSlider {
case red
case green
case blue
var title: String {
String(describing: self).capitalized
}
var tintColor: Color {
switch self {
case .red:
return .red
case .green:
return .green
case .blue:
return .blue
}
}
}
This declares a new enum
type with three cases — red
, green
, and blue
, the three possible values of RGB. It also has a property for the title and tint color that you’ll use to build the slider view.
Next, create a new SwiftUI file and name it RGBSliderView.swift.
Now, add the properties of this view, under the type declaration:
let rgbSlider: RGBSlider
@Binding var value: Double
The first property is a case of RGBSlider
, either .red
, .green
or .blue
. You’ll use this soon to build the body of the view. The second property is a Binding variable of the value of the slider. SwiftUI will use this to bind its value to the slider.
Now, replace the code inside the body with:
VStack(spacing: 0) {
Text(rgbSlider.title)
Slider(value: $value, in: 0...255)
.tint(rgbSlider.tintColor)
}
This code resembles a lot the code you see in ContentView.swift, except here it will use the properties of RGBSliderView
to build the correct UI.
Before you move on, there’s a compilation error you need to fix. Inside the preview code, change:
RGBSliderView()
to
RGBSliderView(
rgbSlider: .red,
value: .constant(50)
)
.padding()
This creates a preview of RGBSliderView
with the .red
case and a constant binding value of 50.
Now that you’re done creating your custom view, use it to remove the duplicated code.
Go back to ContentView.swift and replace the following code:
VStack {
VStack(spacing: 0) {
Text("Red")
Slider(value: $red, in: 0...255)
.tint(.red)
}
VStack(spacing: 0) {
Text("Green")
Slider(value: $green, in: 0...255)
.tint(.green)
}
VStack(spacing: 0) {
Text("Blue")
Slider(value: $blue, in: 0...255)
.tint(.blue)
}
}
with:
VStack {
RGBSliderView(rgbSlider: .red, value: $red)
RGBSliderView(rgbSlider: .green, value: $green)
RGBSliderView(rgbSlider: .blue, value: $blue)
}
Build and run.
Notice that nothing changes, but the amount of code you’re using to build ContentView
has exponentially decreased. Only three lines now define the three sliders!
That’s really good for maintainability and readability.