Swift and SwiftUI tutorials for iOS and Swift Developers - SWIFTPROGRAMMING.COM

How to Add a Custom Icon to System Dialogs in SwiftUI

With iOS 27, Apple introduces a simple way to customize the appearance of system dialogs in SwiftUI. The new .dialogIcon() modifier allows developers to add a custom icon to supported system dialogs without having to build a completely custom dialog from scratch.

In this tutorial, we’ll explore how to add custom icon to system dialogs in SwiftUI, how .dialogIcon() works, and how it can be combined with other SwiftUI modifiers in a modern Swift application.

Whether you are an experienced iOS Developer or just getting started with SwiftUI, this approach makes system dialogs more recognizable while keeping your interface aligned with Apple’s design system.

Requirements

To follow this tutorial, you’ll need:

  • Xcode with an iOS 27 SDK
  • A project using SwiftUI
  • A deployment target that supports the new dialog customization APIs
  • Basic knowledge of Swift and SwiftUI modifiers

Create a new iOS project in Xcode and make sure your app uses SwiftUI for its interface.

Creating a Basic System Dialog

Let’s start with a simple SwiftUI view that presents a system dialog.

import SwiftUI

struct ContentView: View {
    @State private var showDialog = false

    var body: some View {
        Button("Show Dialog") {
            showDialog = true
        }
        .confirmationDialog(
            "Delete this item?",
            isPresented: $showDialog
        ) {
            Button("Delete", role: .destructive) {
                // Delete the item
            }

            Button("Cancel", role: .cancel) { }
        }
    }
}

The .confirmationDialog() modifier presents a system-provided dialog containing actions. Because the dialog is managed by the system, its appearance automatically adapts to the current platform and presentation environment.

Now let’s customize its icon.

The .dialogIcon() Modifier

The most important addition is .dialogIcon().

You can attach it directly to the dialog configuration to provide a custom icon:

.confirmationDialog(
    "Delete this item?",
    isPresented: $showDialog
) {
    Button("Delete", role: .destructive) {
        // Delete the item
    }

    Button("Cancel", role: .cancel) { }
}
.dialogIcon(Image(systemName: "trash"))

Here, Image(systemName:) creates an SF Symbol that represents the action taking place in the dialog.

For example, you could use:

.dialogIcon(Image(systemName: "exclamationmark.triangle"))

for a warning dialog, or:

.dialogIcon(Image(systemName: "person.crop.circle.badge.plus"))

for a dialog related to adding a user.

The important advantage is that you continue using the native system dialog rather than recreating the entire interface yourself.

Using .dialogIcon() With SF Symbols

SF Symbols are particularly useful when working with .dialogIcon() because they integrate naturally with Apple’s visual language.

For example:

.dialogIcon(
    Image(systemName: "folder.badge.plus")
)

Using SF Symbols also means that your icon can automatically benefit from the visual characteristics of the platform.

As an iOS Developer, you should generally choose an icon that communicates the purpose of the dialog instead of simply decorating it.

The .confirmationDialog() Modifier

The .confirmationDialog() modifier is responsible for presenting the system dialog.

A typical implementation looks like this:

.confirmationDialog(
    "Delete Project",
    isPresented: $showDialog,
    titleVisibility: .visible
) {
    Button("Delete", role: .destructive) {
        deleteProject()
    }

    Button("Cancel", role: .cancel) { }
}
.dialogIcon(Image(systemName: "trash"))

The titleVisibility parameter controls whether the dialog title is visible.

Using .confirmationDialog() together with .dialogIcon() is a convenient approach when you want a recognizable visual element without implementing a custom presentation.

The .buttonStyle() Modifier

The buttons inside a system dialog can also use SwiftUI button configuration and styling where supported.

For example, your surrounding interface might use:

Button("Delete") {
    showDialog = true
}
.buttonStyle(.borderedProminent)

The button that opens the dialog belongs to your application’s interface, while the actions inside the system dialog remain controlled by the system.

This distinction is important when designing consistent experiences with SwiftUI.

Complete Example

Here is the complete example:

import SwiftUI

struct ContentView: View {
    @State private var showDialog = false

    var body: some View {
        VStack {
            Button("Delete Project") {
                showDialog = true
            }
        }
        .confirmationDialog(
            "Delete this project?",
            isPresented: $showDialog,
            titleVisibility: .visible
        ) {
            Button("Delete", role: .destructive) {
                deleteProject()
            }

            Button("Cancel", role: .cancel) { }
        }
        .dialogIcon(
            Image(systemName: "trash")
        )
    }

    private func deleteProject() {
        // Perform deletion
    }
}

The key part is the .dialogIcon() modifier. It adds a custom visual representation while allowing the system to continue managing the dialog’s presentation and behavior.

Why Use .dialogIcon()?

For an iOS Developer, the main benefit of .dialogIcon() is simplicity. Instead of creating a custom dialog with your own layout, background, buttons, animations, accessibility behavior, and presentation logic, you can continue using the native system component.

This approach also keeps your application closer to Apple’s platform conventions.

When choosing an icon, focus on meaning and context. A trash icon works well for destructive actions, while warning, information, sharing, or authentication-related SF Symbols can communicate different intentions.

Conclusion

The new .dialogIcon() modifier provides a straightforward way to customize supported system dialogs in SwiftUI on iOS 27. By combining .confirmationDialog() with .dialogIcon(), you can add meaningful visual context without abandoning the native system experience.

If you’re learning how to add custom icon to system dialogs in SwiftUI, the main concept is simple: configure your system dialog as usual and use .dialogIcon() to provide the appropriate image.

With Swift, Xcode, and SwiftUI, this small customization can make system dialogs more recognizable while keeping your app’s UI consistent with the platform.

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

How to Request App Reviews in SwiftUI

Related Posts