# Multiple alert in single View SwiftUI


Ever tried adding multiple `.alert()` modifiers to a SwiftUI view, only to watch in frustration as only one actually works? You're not alone. SwiftUI's alert system has a quirk that catches developers off guard: chaining alert modifiers simply doesn't work the way you'd expect. But there's good news—with the right approach, you can handle as many alerts as you need from a single view, and the solution is actually more elegant than you might think.

## Method 1: Using Optional Identifiable Items (Recommended)

This is the most elegant approach using SwiftUI's built-in alert modifier with identifiable items.

```swift
struct ContentView: View {
    enum ActiveAlert: Identifiable {
        case delete, save, error
        
        var id: Int {
            hashValue
        }
    }
    
    @State private var activeAlert: ActiveAlert?
    
    var body: some View {
        VStack(spacing: 20) {
            Button("Show Delete Alert") {
                activeAlert = .delete
            }
            
            Button("Show Save Alert") {
                activeAlert = .save
            }
            
            Button("Show Error Alert") {
                activeAlert = .error
            }
        }
        .alert(item: $activeAlert) { alertType in
            switch alertType {
            case .delete:
                return Alert(
                    title: Text("Delete"),
                    message: Text("Are you sure you want to delete?"),
                    primaryButton: .destructive(Text("Delete")) {
                        // Handle delete
                    },
                    secondaryButton: .cancel()
                )
            case .save:
                return Alert(
                    title: Text("Save"),
                    message: Text("Do you want to save changes?"),
                    primaryButton: .default(Text("Save")) {
                        // Handle save
                    },
                    secondaryButton: .cancel()
                )
            case .error:
                return Alert(
                    title: Text("Error"),
                    message: Text("Something went wrong"),
                    dismissButton: .default(Text("OK"))
                )
            }
        }
    }
}
```

**Why this works:** SwiftUI's `.alert(item:)` modifier watches for changes to an optional identifiable value. When the value changes from nil to a specific case, the corresponding alert appears. This uses a single alert modifier that dynamically displays different alerts based on the enum value.

## Method 2: Using a Custom Alert Manager

For complex scenarios with many alerts across multiple views, create a dedicated manager to handle alert state.

```swift
class AlertManager: ObservableObject {
    enum AlertType: Identifiable {
        case delete(item: String)
        case save
        case error(message: String)
        case success
        
        var id: String {
            switch self {
            case .delete: return "delete"
            case .save: return "save"
            case .error: return "error"
            case .success: return "success"
            }
        }
    }
    
    @Published var currentAlert: AlertType?
    
    func showAlert(_ type: AlertType) {
        currentAlert = type
    }
}

struct ContentView: View {
    @StateObject private var alertManager = AlertManager()
    
    var body: some View {
        VStack(spacing: 20) {
            Button("Show Delete Alert") {
                alertManager.showAlert(.delete(item: "Photo"))
            }
            
            Button("Show Save Alert") {
                alertManager.showAlert(.save)
            }
            
            Button("Show Error Alert") {
                alertManager.showAlert(.error(message: "Network error"))
            }
        }
        .alert(item: $alertManager.currentAlert) { alertType in
            switch alertType {
            case .delete(let item):
                return Alert(
                    title: Text("Delete \(item)"),
                    message: Text("This action cannot be undone"),
                    primaryButton: .destructive(Text("Delete")) {
                        // Handle delete
                    },
                    secondaryButton: .cancel()
                )
            case .save:
                return Alert(
                    title: Text("Save Changes"),
                    message: Text("Save your work?"),
                    primaryButton: .default(Text("Save")) {
                        // Handle save
                    },
                    secondaryButton: .cancel()
                )
            case .error(let message):
                return Alert(
                    title: Text("Error"),
                    message: Text(message),
                    dismissButton: .default(Text("OK"))
                )
            case .success:
                return Alert(
                    title: Text("Success"),
                    message: Text("Operation completed"),
                    dismissButton: .default(Text("OK"))
                )
            }
        }
    }
}
```

**Why this works:** The AlertManager encapsulates all alert logic in a separate class, making it reusable across your app. You can inject this manager into multiple views via the environment, allowing centralized alert handling throughout your application.

## When to Use Each Method

**Use Method 1 (Identifiable Enum) when:**
- You have multiple distinct alert types in a single view
- Alerts are self-contained within one screen
- You want the simplest, most SwiftUI-native solution
- You need to pass minimal associated data with alerts

**Use Method 2 (Alert Manager) when:**
- You have many alerts across multiple views in your app
- You need centralized alert management and reusability
- You want to share alert logic between different screens
- You need to trigger alerts from view models or business logic
- You want to pass complex associated data with alerts

## The Key Takeaway

The fundamental principle is simple: use a single `.alert()` modifier with an optional identifiable value. Whether you manage that value with a simple enum or a dedicated manager class depends on your app's complexity. Both methods follow the same core pattern—they just differ in how they organize the alert state.

Never chain multiple `.alert()` modifiers on the same view. Only the last modifier in the chain will function, leaving you with broken alert logic and confused users.
