Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Another Variable '__' used before being initialized question

Tags:

swift

swiftui

I have searched here. I have seen and assume this is affecting it

Class initialisation in Swift is a two-phase process. In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.

When I run the below code I get the error Variable 'self.string' used before being initialized.

But it applies to every variable I don't change to a var and initialize. What is going on here?

Here is the error:

enter image description here

The below doesn't work.

struct IntTextField<T: Numeric & LosslessStringConvertible>: View {
    @Binding var number: T?
    @State private var string: String
    private let isDecimalAllowed: Bool

    private let title: LocalizedStringKey
    private let onEditingChanged: (Bool) -> Void
    private let onCommit: () -> Void

    public init(_ titleKey: LocalizedStringKey, number: Binding<T?>, isDecimalAllowed: Bool, onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void = {}) {
        self._number = number
        self.string = "Why doesn't this work????"

        self.isDecimalAllowed = isDecimalAllowed

        self.title = titleKey
        self.onEditingChanged = onEditingChanged
        self.onCommit = onCommit
    }

    var body: some View {
        TextField(title, text: $string, onEditingChanged: onEditingChanged, onCommit: onCommit)
            .numericText(text: $string, number: $number, isDecimalAllowed: isDecimalAllowed)
            .modifier(KeyboardModifier(isDecimalAllowed: isDecimalAllowed))
    }
}

The below works (I have to change them all to var and initialize them to something), why do I have to do this?

struct IntTextField<T: Numeric & LosslessStringConvertible>: View {
    @Binding var number: T?
    // Everything below is changed to var and initialized
    @State private var string: String = ""
    private var isDecimalAllowed: Bool = false

    private var title: LocalizedStringKey = ""
    private var onEditingChanged: (Bool) -> Void = { _ in }
    private var onCommit: () -> Void = {}
    // To here

    init(_ titleKey: LocalizedStringKey, number: Binding<T?>, isDecimalAllowed: Bool, onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void = {}) {
        self._number = number
        self.string = "Why does this work????"

        self.isDecimalAllowed = isDecimalAllowed

        self.title = titleKey
        self.onEditingChanged = onEditingChanged
        self.onCommit = onCommit
    }

    var body: some View {
        TextField(title, text: $string, onEditingChanged: onEditingChanged, onCommit: onCommit)
            .numericText(text: $string, number: $number, isDecimalAllowed: isDecimalAllowed)
            .modifier(KeyboardModifier(isDecimalAllowed: isDecimalAllowed))
    }
}
like image 297
Diesel Avatar asked Jul 31 '26 01:07

Diesel


1 Answers

That variable is a little different than normal because of its @State property wrapper. To initialize it here without that error, you need to do this:

self._string = State(initialValue: "Why doesn't this work????")

The _ lets you access string without the property wrapper. In fact, you're already doing this on the line above with your Binding with a similar strategy.

On your second example, string already has a default value of "", so the compiler isn't worried about it not being set yet.

like image 175
jnpdx Avatar answered Aug 02 '26 17:08

jnpdx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!