debratton
debratton

Reputation: 51

Swift UI passing a binding to another view for alert with an init

I am able to pass bindings to another view without an init and it works perfectly. But if I try with a view that has an init I can't get past the errors.

struct ContentView: View {
    // MARK: - PROPERTIES
    @State private var showAlert = false
    @State private var alert: Alert? = nil
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    
    // MARK: - BODY
    var body: some View {
        VStack {
            Button(action: {
                alertTitle = "Alert 1"
                alertMessage = "From Main View"
                showAlert.toggle()
            }, label: {
                Text("Show Parent Alert")
            })
            
            // MARK: - TESTVIEW1
            TestView1(showAlert: $showAlert, alert: $alert, alertTitle: $alertTitle, alertMessage: $alertMessage)
        } // END:VSTACK
        .alert(isPresented: $showAlert, content: {
            Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("Close")))
        })
    }
}

struct TestView1: View {
    // MARK: - PROPERTIES
    @Binding var showAlert: Bool
    @Binding var alert: Alert?
    @Binding var alertTitle: String
    @Binding var alertMessage: String
    
    // MARK: - BODY
    var body: some View {
        VStack {
            Button(action: {
                alertTitle = "Alert 2"
                alertMessage = "From TestView1"
                showAlert.toggle()
            }, label: {
                Text("Show View-1 Alert")
            })
            
            TestView2(showAlert: $showAlert, alert: $alert, alertTitle: $alertTitle, alertMessage: $alertMessage)
        } // END:VSTACK
    }
}

That works fine, but if I have an init, I get an error "Cannot assign value of type 'Alert?.Type' to type 'Alert'"

struct TestView1: View {
    // MARK: - PROPERTIES
    @Binding var showAlert: Bool
    @Binding var alert: Alert?
    @Binding var alertTitle: String
    @Binding var alertMessage: String
    
    init(showAlert: Binding<Bool>, alert: Binding<Alert>, alertTitle: Binding<String>, alertMessage: Binding<String>) {
        self.showAlert = false
        self.alert = Alert?
        self.alertTitle = ""
        self.alertMessage = ""
    }

Upvotes: 0

Views: 502

Answers (1)

New Dev
New Dev

Reputation: 49590

If you have an init that accepts a Binding, you need to assign the Binding - not the value - to the @Binding property. You do that by using the _ prefix.

init(showAlert: Binding<Bool>, 
     alert: Binding<Alert>, 
     alertTitle: Binding<String>, 
     alertMessage: Binding<String>) {

   self._showAlert = showAlert
   self._alert = alert
   self._alertTitle = alertTitle
   self._alertMessage = alertMessage
}

Upvotes: 2

Related Questions