How to show image and text in menu item in SwiftUI for macOS

Issue #719

From SwiftUI 2 for macOS 11.0, we have access to Menu for creating menu and submenu. Usually we use Button for interactive menu items and Text for disabled menu items.

The easy way to customize menu with image is to call Menu with content and label. Pay attention to how we use Button and Label inside Content to create interactive menu items

1
2
3
4
5
6
7
8
9
10
11
12
13
Menu(
content: {
ForEach(collections) { collection in
Button(action: {) {
Label(collection.name, systemImage: SFSymbol.star.rawValue)
}
}
},
label: {
Image(systemName: SFSymbol.bookmarkFill.rawValue)
Text("Add to collection")
}
)

We can also use Image and Text separately. By default SwiftUI wraps these inside HStack automatically for us. For now, color has no effect in Menu, but it works on Text

1
2
3
4
Image(systemName: SFSymbol.bookmarkFill.rawValue)
.foregroundColor(Color.red)
Text(collection.name)
.foregroundColor(Color.green)

One way to mitigate this is to use Text with icon font. Here I use my FontAwesomeSwiftUI

There’s a problem that only the first Text is shown

1
2
3
4
Text(collection.icon)
.font(.awesome(style: .solid, size: 18))
.foregroundColor(Color.red)
Text(collection.name)

The solution is to concatenate Text. In SwiftUI, Text has + operator that allows us to make cool attributed texts

Screenshot 2020-12-23 at 07 34 40
1
2
3
4
Text(collection.icon)
.font(.awesome(style: .solid, size: 18))
.foregroundColor(Color.red)
+ Text(collection.name)

Updated at 2020-12-23 06:35:31

Comments