When the user taps a button or a navigation link, it’s pretty clear that SwiftUI should trigger the default action for those views. But what if they press and hold on something? On older iPhones users could trigger a 3D Touch by pressing hard on something, but the principle is the same: the user wants more options for whatever they are interacting with.
SwiftUI lets us attach context menus to objects to provide this extra functionality, all done using the contextMenu()
modifier. You can pass this a selection of buttons and they’ll be shown in order, so we could build a simple context menu to control a view’s background color like this:
struct ContentView: View {
@State private var backgroundColor = Color.red
var body: some View {
VStack {
Text("Hello, World!")
.padding()
.background(backgroundColor)
Text("Change Color")
.padding()
.contextMenu {
Button("Red") {
backgroundColor = .red
}
Button("Green") {
backgroundColor = .green
}
Button("Blue") {
backgroundColor = .blue
}
}
}
}
}
Just like TabView
, each item in a context menu can have text and an image attached to it using a Label
view.
For example, we could use one of Apple’s SF Symbols like this:
Button("Red", systemImage: "checkmark.circle.fill") {
backgroundColor = .red
}
Apple really likes these menu items to look somewhat uniform across apps, so if you were to try adding a foregroundStyle()
modifier to the above code it would be ignore – trying to color menu items randomly just won’t work.
If you really want that item to appear red, which as you should know means destructive, you should use a button role instead:
Button("Red", systemImage: "checkmark.circle.fill", role: .destructive) {
backgroundColor = .red
}
I have a few tips for you when working with context menus, to help ensure you give your users the best experience:
Remember, context menus are by their nature hidden, so please think twice before hiding important actions in a context menu.
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.