I'm probably not understanding the basics and confused, but I couldn't figure out the reason of things below. Ok, what I want to do is pass Int64 to sub view and show Toggles based on bits and set the bits back to parent view like this:
struct ContentView: View {
@State var bits: Int64 = 5
var body: some View {
Form {
Section {
SectionView(title: "Section", withBits: $bits)
} header: {
Text("Toggle")
}
}
}
}
struct SectionView: View {
let title: String
@Binding var bits: Int64
@State private var first: Bool
@State private var second: Bool
@State private var third: Bool
init(title: String, withBits: Binding<Int64>) {
self.title = title
self._bits = withBits
self.first = self.bits & 1 == 1
self.second = self.bits & 2 == 2
self.third = self.bits & 4 == 4
}
var body: some View {
VStack {
HStack {
Text(self.title)
}
HStack {
Toggle("Toggle 1", isOn: self.$first)
.onChange(of: self.first) { newValue in
if newValue {
self.bits |= 1
}
else {
self.bits &= ~1
}
}
}
HStack {
Toggle("Toggle 2", isOn: self.$second)
.onChange(of: self.second) { newValue in
if newValue {
self.bits |= 2
}
else {
self.bits &= ~2
}
}
}
HStack {
Toggle("Toggle 3", isOn: self.$third)
.onChange(of: self.third) { newValue in
if newValue {
self.bits |= 4
}
else {
self.bits &= ~4
}
}
}
}
.onChange(of: self.bits) { newValue in
print("bits: \(bits)")
}
}
}
But it won't compile. Saying "'self' used before all stored properties are initialized" error.
So I set default values to all Bool vars like this:
@State private var first: Bool = false
@State private var second: Bool = false
@State private var third: Bool = false
It compiles now but cannot overwrite them in int(), below lines are completely ignored.
self.first = self.bits & 1 == 1
self.second = self.bits & 2 == 2
self.third = self.bits & 4 == 4
Moving above three lines to onAppear() worked. But still I want to know why they won't be overwritten in init() and cleanest way.
CodePudding user response:
Avoid using in your initialiser the variables being initialised, if you can. The Binding
has no value in the beginning, that's why you need to wait for your View to appear.
Try replacing the initialisation for your 3 variables with the following code (using init()
and not .onAppear()
):
self.first = withBits.wrappedValue & 1 == 1 // Why using an always true condition? OK if this is just a placeholder
self.second = withBits.wrappedValue & 2 == 2
self.third = withBits.wrappedValue & 4 == 4