divadretlaw / CustomAlert

🔔 Custom Alert for SwiftUI
MIT License
190 stars 18 forks source link

Alert does not get updated title when using variable #16

Closed david-qualias closed 7 months ago

david-qualias commented 8 months ago

I used the demo to show the issue, alert shows empty text, only second opening has correct value. For now i delay showing the alert so gets new value but seems a bit hacky, any solution? The native Alert() has no issue.

struct SimpleAlerts: View {
    @State private var showNative = false
    @State private var showCustom = false

    @State var text = ""

    var body: some View {
        Section {
            Button {
                showNative = true
            } label: {
                Text("Native Alert")
            }
            .alert("Native Alert", isPresented: $showNative) {
                Button(role: .cancel) {

                } label: {
                    Text("Cancel")
                }
            } message: {
                Text("Some Message")
            }

            Button {
                showCustom = true
                text = "text"
            } label: {
                Text("Custom Alert")
            }
            .customAlert("Custom Alert", isPresented: $showCustom) {
                Text(text)
            } actions: {
                Button(role: .cancel) {

                } label: {
                    Text("Cancel")
                }
            }
        } header: {
            Text("Simple")
        }
    }
}
rineek commented 7 months ago

For this demo code I found an alternative solution to introduce view-model:

struct SimpleAlerts: View {
    @State private var showNative = false
    @State private var showCustom = false

    @StateObject var simpleAlertsViewModel = SimpleAlertsViewModel()

    var body: some View {
        Section {
            Button {
                showNative = true
                simpleAlertsViewModel.nativeText = "Native Text"
            } label: {
                Text("Native Alert")
            }
            .alert("Native Alert", isPresented: $showNative) {
                Button(role: .cancel) {
                } label: {
                    Text("Cancel")
                }
            } message: {
                Text(simpleAlertsViewModel.nativeText)
            }

            Button {
                showCustom = true
                simpleAlertsViewModel.customText = "Custom Text"
            } label: {
                Text("Custom Alert")
            }
            .customAlert("Custom Alert", isPresented: $showCustom) {
                Text(simpleAlertsViewModel.customText)
            } actions: {
                Button(role: .cancel) {
                } label: {
                    Text("Cancel")
                }
            }
        }
    }
}

class SimpleAlertsViewModel: ObservableObject {
    @Published var nativeText = ""
    @Published var customText = ""
}

Screenshot 2024-03-19 at 16 48 14

However this solution doesn't work if that text is in the title(works for native alert):

struct SimpleAlerts: View {
    @State private var showNative = false
    @State private var showCustom = false

    @StateObject var simpleAlertsViewModel = SimpleAlertsViewModel()

    var body: some View {
        Section {
            Button {
                showNative = true
                simpleAlertsViewModel.nativeText = "Native Text"
            } label: {
                Text("Native Alert")
            }
            .alert(simpleAlertsViewModel.nativeText, isPresented: $showNative) {
                Button(role: .cancel) {
                } label: {
                    Text("Cancel")
                }
            } message: {
                Text(simpleAlertsViewModel.nativeText)
            }

            Button {
                showCustom = true
                simpleAlertsViewModel.customText = "Custom Text"
            } label: {
                Text("Custom Alert")
            }
            .customAlert(simpleAlertsViewModel.customText, isPresented: $showCustom) {
                Text(simpleAlertsViewModel.customText)
            } actions: {
                Button(role: .cancel) {
                } label: {
                    Text("Cancel")
                }
            }
        }
    }
}

class SimpleAlertsViewModel: ObservableObject {
    @Published var nativeText = ""
    @Published var customText = ""
}

Screenshot 2024-03-19 at 16 47 49

divadretlaw commented 7 months ago

Hello, thank you for opening an issue and for the example code.

I found a way to address your issues, but for the title to also update it requires a slightly different API.

.customAlert(isPresented: $showCustom) {
    Text("Custom Alert: \(text)")
} content: {
    Text("Some Message: \(text)")
} actions: {
    Button(role: .cancel) {

    } label: {
        Text("Cancel")
    }
}

The new version 3.3.0 should fix this issue, please let me know if any further issue arises.