config 2 alerts messages in button swiftUI

498 Views Asked by At

I going learn swift and swiftUI. I make application for organize notes by category. you can find my project in my GitHub if you need. https://github.com/yoan8306/List-Notes I have problem. I think it's simple. I would like make 2 alerts messages. The first it's when save is success and the second is when they are problem like one field is empty or category is empty.

private func checkNoteIsOk() -> Bool{
        if !noteTitleField.isEmpty && !noteField.isEmpty && categorySelected != nil {
          return true
        } else {
            return false
        }
    }
.

Button(action: {
                        guard checkNoteIsOk() else {
                       presentAlert = true
                            return
                        }
                        coreDM.saveNote(noteData: noteField, noteTitle: noteTitleField,
                                          noteDate: Date(), noteCategory: categorySelected!)
                        emptyField()
                        
                        saveSuccess = true
                          },
                            label: {
                              Text("Save")
                            }
                    ) 
    } 

   
//end Vstak
      .navigationTitle("Create new note")
      
      .alert(isPresented: $presentAlert) {
                Alert(title: Text("Error !"), message: Text("Not saved"),
                dismissButton: .default(Text("OK"))) }
            
      .alert(isPresented: $saveSuccess) {
        Alert(title: Text("Success !"), message: Text("Insert with success !"),
        dismissButton: .default(Text("OK"))) }

I think it's because they are two alerts messages. And only the last message alert can display. Thank you for your answer and your help.

2

There are 2 best solutions below

1
Raja Kishan On BEST ANSWER

For multiple alerts in a single view, you can use an enum.

First, you need to create an enum like this and define all the alert message

enum AlertType: Identifiable {
    var id: UUID {
        return UUID()
    }
    
    case success
    case error
    
    var title: String {
        switch self {
        case .success:
            return "Success !"
        case .error:
            return "Error !"
        }
    }
    
    var message: String {
        switch self {
        case .success:
            return "Insert with success !"
        case .error:
            return "This category already exist !!"
        }
    }
}

now create one state var in the view.

struct NewCategoryView: View {
    @State private var alertType: AlertType?
    
    // Other code
}

and add the alert at the end

//end Vstak
.navigationTitle("New Category")
.onAppear(perform: { updateCategoryList()} )
.alert(item: self.$alertType, content: { (type) -> Alert in
    Alert(title: Text(type.title), message: Text(type.message),
          dismissButton: .default(Text("OK")))
})

now show the alert by assigning the value. Like this

if condition_true {
    alertType = AlertType.success //<-- Here
} else {
    alertType = AlertType.error //<-- Here
}
0
Damiaan Dufaux On

While [Raja]'s answer is working. I don't think it is ideal because

  • it generates random UUID's which Apple discourages when it's not needed.
  • it does requires multiple switch statements where only one is needed.

A more simple solution might be to define the enum like this

enum ResultAlert: Int8, Identifiable {
    case success, error

    var id: some Hashable { rawValue }
    var content: Alert {
        switch self {
        case .success: return Alert(title: Text("Success!"))
        case .error: return Alert(title: Text("Oy, error..."))
        }
    }
}

Then the rest is the same as Raja's answer:

Add it as a @State variable to your view

@State var resultAlert: ResultAlert?

Activate it using resultAlert = .success or resultAlert = .error. Deactivate it using resultAlert = .none

And present it like this:

.alert(item: $resultAlert, content: \.content)