Reputation: 43
I am new to SwiftUI and am facing an issue. The variable selectedColor is not getting updated, when I move the slider. My aim is as I move the slider the ColorView Background color should change and appropriate color should be shown as background but color is not getting changed. Any pointers to solve the problem would be helpful. This is how it looks while I expect a capsule with selected color aroun #837c7c.
struct GradientView: View {
let name: String
@State private var redValue = 124.0
@State private var greenValue = 124.0
@State private var blueValue = 124.0
@State private var selectedColor: Color = .green
@State var isEditing = false
var body: some View {
VStack(spacing: 0) {
VStack {
HStack {
VStack {
Slider(value: $redValue,
in: 0...255,
step: 1
).onChange(of: self.redValue, perform: { newValue in
self.sliderChanged()
})
.accentColor(.red)
Slider(value: $greenValue,
in: 0...255,
step: 1
).onChange(of: self.greenValue, perform: { newValue in
self.sliderChanged()
})
.accentColor(.green)
Slider(value: $blueValue,
in: 0...255,
step: 1
).onChange(of: self.blueValue, perform: { newValue in
self.sliderChanged()
}).accentColor(.blue)
}
VStack {
ColorView(selectedColor: $selectedColor)
.padding()
//.foregroundColor(.black)
}
//.background(selectedColor)//.background(Capsule().fill(selectedColor))
//.init(red: redValue, green: greenValue, blue: blueValue)
}
}
}
.padding()
.frame(maxHeight: .infinity, alignment: .top)
.navigationTitle(name)
}
func sliderChanged() {
selectedColor = Color.init(red: redValue, green: greenValue, blue: blueValue)
print("Slider value changed to ")
print("\(redValue):\(greenValue):\(blueValue)")
}
}
struct ColorView: View {
@Binding var selectedColor: Color
var body: some View {
let components = selectedColor.cgColor?.components
Text("#\(String(format:"%02X", Int(components?[0] ?? 0)))\(String(format:"%02X", Int(components?[1] ?? 0)))\(String(format:"%02X", Int(components?[2] ?? 0)))")
.background(Capsule().fill(selectedColor))
.padding()
.font(.system(.caption).bold())
}
}
Upvotes: 2
Views: 219
Reputation: 257749
The Color constructor with components requires colour in 0...1, so we just need to convert slider value to needed range:
selectedColor = Color.init(red: CGFloat(redValue)/255,
green: CGFloat(greenValue/255),
blue: CGFloat(blueValue)/255)
Tested with Xcode 14 / iOS 16
Update: however instead I recommend to change selectedColor
to CGColor
type, because SwiftUI.Color.cgColor
can return nil (as documented)
so more appropriate solution would be:
@State private var selectedColor: CGColor = UIColor.green.cgColor // << any default !!
// ...
func sliderChanged() {
selectedColor = CGColor.init(red: CGFloat(redValue)/255, green: CGFloat(greenValue/255), blue: CGFloat(blueValue)/255, alpha: 1.0)
print("Slider value changed to ")
print("\(redValue):\(greenValue):\(blueValue)")
}
}
struct ColorView: View {
@Binding var selectedColor: CGColor
var body: some View {
let components: [CGFloat] = selectedColor.components ?? [0, 0, 0]
Text("#\(String(format:"%02X", Int(components[0]*255)))\(String(format:"%02X", Int(components[1]*255)))\(String(format:"%02X", Int(components[2]*255)))")
.padding()
.background(Capsule().fill(Color(selectedColor)))
.font(.system(.caption).bold())
}
}
Upvotes: 1