How it works
A Menu presents a set of actions and choices behind a single control, revealing them in a pop-up only when the person interacts with it. Reach for it when a view has several related commands that would clutter the interface if shown all at once — it keeps the primary surface clean while keeping secondary actions one tap away. Unlike a button, which performs one action, a menu defers to a list of child controls and lets the system handle the presentation and dismissal of that list.
Create the menu with a label and a content closure
The
Menuinitializer takes a label that names the control and a trailing closure that builds the items shown when it opens. HereMenu("Options")uses the string-label convenience initializer, so SwiftUI renders the title and a disclosure indicator for you; the closure following it is the menu's content.Populate the menu with action controls
The content closure holds the choices, most commonly
Buttoninstances whose actions run when selected. In the example,Button("Rename"),Button("Duplicate"), andButton("Delete")each setlastAction, and the menu closes automatically once one is chosen.Group and separate items with Divider
Because the content is a normal view builder, you can structure it the way you would any stack of controls. Placing a
Divider()betweenButton("Duplicate")andButton("Delete")draws a separator line that visually splits routine actions from a more consequential one.Convey intent with a button role
A control inside the menu can carry a
rolethat tells the system how to style and treat it.Button("Delete", role: .destructive)marks the delete action as destructive, so the platform renders it with the standard warning emphasis to signal that it removes something.
Button("Archive") { lastAction = "Archive" } above the Divider() and watch it join the menu's list while staying grouped with the non-destructive actions.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct MenuDemo: View {
@State private var lastAction = "None"
var body: some View {
VStack(spacing: 16) {
Menu("Options") {
Button("Rename") { lastAction = "Rename" }
Button("Duplicate") { lastAction = "Duplicate" }
Divider()
Button("Delete", role: .destructive) { lastAction = "Delete" }
}
Text("Last action: \(lastAction)")
.foregroundColor(.secondary)
}
.padding()
}
}