我试图制作一个具有自定义init功能的颜色选择器,以设置原始颜色。并具有3个状态变量(色相,饱和度,亮度)以保存将由较小的组件更改的值。在尝试了多种方法之后,我仍然无法在自定义init函数中更改3个@State变量的值。好吧谁能帮我?谢谢
struct ColorPicker: View {
@State var saturation: CGFloat = 0.5
@State var brightness: CGFloat = 0.5
@State var hue: CGFloat = 0.5
@State var alpha: CGFloat = 1
var oriColor : UIColor? = nil
var oriHue: CGFloat = 0
var oriSaturation: CGFloat = 0
var oriBrightness: CGFloat = 0
init(oriColor:UIColor?) {
self.oriColor = oriColor
if let color = oriColor{
color.getHue(&oriHue, saturation: &oriSaturation, brightness: &oriBrightness, alpha: &alpha)
self._hue = State(initialValue:oriHue)
self._saturation = State(initialValue:oriSaturation)
self._brightness = State(initialValue:oriBrightness)
self.hue = oriHue
debugPrint("set value:\(hue)")
}
}
var body: some View {
debugPrint("make view with:\(self.hue)")
let bindingSaturation = Binding<CGFloat>(get: {return self.saturation}, set: {val in self.saturation = val})
let bindingBrightness = Binding<CGFloat>(get: {return self.brightness}, set: {val in self.brightness = val})
let bindingHue = Binding<CGFloat>(get: {return self.hue}, set: {val in self.hue = val})
debugPrint("make view with:\(self.hue)")
return Text("debugging")
}
}
Click here to view code and output
---更新应用Procrastin8的答案
我根据您的建议更改了代码
struct ColorPicker: View {
@State var hue: CGFloat
var oriHue: CGFloat = 0.5
var oriSaturation: CGFloat = 0.5
var oriBrightness: CGFloat = 0.5
var oriAlpha: CGFloat = 1
init(oriColor:UIColor?) {
if let color = oriColor {
color.getHue(&oriHue, saturation: &oriSaturation, brightness: &oriBrightness, alpha: &oriAlpha)
self.hue = oriHue
}
else {
self._hue = State(initialValue:oriHue)
}
}
var body: some View {
debugPrint("make view with:\(self.hue)")
return VStack {
BrightnessGrid.init(hue: self.$hue)
}
}
}
struct BrightnessGrid : View {
@Binding var hue: CGFloat
var body: some View {
VStack{
Text("hue:\(self.hue)")
}
}
}
但是在初始化所有存储的属性之前使用了“'self'”错误,如附件图像here
中所示我来宾,原因是当我们有自定义的init时,默认的初始化程序将不起作用,因此我们必须自行手动设置@State变量的值。然后回到第一种情况。
现在的init函数是
init(oriColor:UIColor?) {
if let color = oriColor {
color.getHue(&oriHue, saturation: &oriSaturation, brightness: &oriBrightness, alpha: &oriAlpha)
}
self._hue = State(initialValue:oriHue)
}
仍然无法正常工作。
-更新2 我创建了一个新的测试项目,并应用了User3441734的答案。在主视图中应用时,效果很好。然后,我像这样将其分离成模块。
import SwiftUI
struct ContentView: View {
var colorA: UIColor = UIColor.orange
var colorB: UIColor = UIColor.blue
@State var oriColor: UIColor? = nil
func changeToColorA(){
oriColor = colorA
}
func changeToColorB(){
oriColor = colorB
}
var body: some View {
VStack{
HStack{
Button(action:changeToColorA){
Text("Color A")
}
Button(action:changeToColorB){
Text("Color B")
}
}
TestView(oriColor: oriColor)
}
}
}
struct TestView: View {
@State var hue: CGFloat
var oriHue: CGFloat = 0.5
var oriSaturation: CGFloat = 0.5
var oriBrightness: CGFloat = 0.5
var oriAlpha: CGFloat = 1
init(oriColor:UIColor?) {
if let color = oriColor {
color.getHue(&oriHue, saturation: &oriSaturation, brightness: &oriBrightness, alpha: &oriAlpha)
}
_hue = State(initialValue: oriHue)
}
var body: some View {
debugPrint("make view with:\(self.hue)")
return VStack {
Text("\(hue)").background(Color(hue: Double(hue), saturation: Double(oriSaturation), brightness: Double(oriBrightness), opacity: Double(oriAlpha)))
.onTapGesture {
self.hue = 0.22
}
Slider(value: $hue, in: 0 ... 1) {
Text("HUE")
}
}
}
}
然后单击颜色A,颜色B时没有任何反应。我做错了什么吗?
答案 0 :(得分:3)
您正在设置默认初始值,然后尝试覆盖State
函数中的init
容器。尝试同时使用计算值或默认值同时设置它们,但都在init
函数中。
struct ColorPicker: View {
@State var saturation: CGFloat
@State var brightness: CGFloat
@State var hue: CGFloat
@State var alpha: CGFloat
init(_ color: UIColor?) {
if let color = color {
// what you had before
} else {
self._saturation = State(initialValue: 0.5)
// etc.
}
}
我也不会完全依赖body
函数中的计算值。尝试仅使用一个标签来打印出这些值,然后查看得到的内容,而不是进行调试打印。
注意:您知道@State
出售Binding
是对projectedValue
的权利吗?
SomeView(colorComponent: "hue", binding: $hue)
答案 1 :(得分:0)
要更改国家的初始值,请使用其基础值
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
@State var hue: CGFloat
var oriHue: CGFloat = 0.5
var oriSaturation: CGFloat = 0.5
var oriBrightness: CGFloat = 0.5
var oriAlpha: CGFloat = 1
init(oriColor:UIColor?) {
if let color = oriColor {
color.getHue(&oriHue, saturation: &oriSaturation, brightness: &oriBrightness, alpha: &oriAlpha)
}
_hue = State(initialValue: oriHue)
}
var body: some View {
debugPrint("make view with:\(self.hue)")
return VStack {
Text("\(hue)").background(Color(hue: Double(hue), saturation: Double(oriSaturation), brightness: Double(oriBrightness), opacity: Double(oriAlpha)))
.onTapGesture {
self.hue = 0.22
}
Slider(value: $hue, in: 0 ... 1) {
Text("HUE")
}
}
}
}
PlaygroundPage.current.setLiveView(ContentView(oriColor: UIColor.orange))
答案 2 :(得分:0)
尝试了许多方法但未成功。我使用的代码可以正常工作。
import SwiftUI
struct ContentView: View {
@State var oriColor: UIColor? = nil
@State var hue: CGFloat = 1
@State var saturation: CGFloat = 1
@State var brightness: CGFloat = 1
@State var alpha: CGFloat = 1
func setColor(_ oriColor: UIColor){
self.oriColor = oriColor
oriColor.getHue(&self.hue, saturation: &self.saturation, brightness: &self.brightness, alpha: &self.alpha)
}
func changeToColorA(){
setColor(UIColor.orange)
}
func changeToColorB(){
setColor(UIColor.blue)
}
var body: some View {
VStack {
HStack {
Button(action:changeToColorA) {
Text("Color A")
}
Button(action:changeToColorB) {
Text("Color B")
}
}
ColorPicker(hue: self.$hue, saturation: self.$saturation, brightness: self.$brightness, alpha: self.$alpha)
}
}
}
struct ColorPicker: View {
@Binding var hue: CGFloat
@Binding var saturation: CGFloat
@Binding var brightness: CGFloat
@Binding var alpha: CGFloat
var body: some View {
return VStack {
TestView.init(hue: self.$hue, saturation: self.$saturation, brightness: self.$brightness, alpha:self.$alpha )
}
}
}
struct TestView: View {
@Binding var hue: CGFloat
@Binding var saturation: CGFloat
@Binding var brightness: CGFloat
@Binding var alpha: CGFloat
var body: some View {
debugPrint("make view with:\(self.hue)")
return VStack {
Text("\(hue)").background(Color(hue: Double(hue), saturation: Double(saturation), brightness: Double(brightness), opacity: Double(alpha)))
Slider(value: $hue, in: 0 ... 1) {
Text("HUE")
}
}
}
}