Cannot set color of Button's Label inside Menu in SwiftUI
Asked Answered
D

2

12

If I create a Menu in SwiftUI (iOS), I cannot set the color of the Buttons inside, e.g.:

Menu("Actions") {
    Button(action: { }) {
        Label("Whatever", systemImage: "pencil")
             .background(Color.red)  // does not work
    }
    .background(Color.red)           // does not work either
    .buttonStyle(RedButtonStyle())   // does not work either
}

struct RedButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label.foregroundColor(Color.red)
    }
}

If instead of Label, I use Text, or Image (I am aware of this), it doesn't work either.

Is there any way to do it?

P.S.: there is another related SO question, but it is very generic and wider in scope.

Dibbuk answered 18/2, 2021 at 11:56 Comment(2)
You can't change the default Menu's buttons style, colors etc. in SwiftUI 2.0. You can try to build your own custom Menu.Bagasse
The link that you posted leads to Apple's sample code on how to create your own it with UIKit. Follow that and then wrap it into a UIViewControllerRepresentable or a UiViewRepresentable to make it work in SwiftUI.Dialecticism
S
20

This is now possible in iOS 15 by setting a Button's role. Documentation

Example:

Menu("Actions") {
    Button(role: .destructive, action: { }) {
        Label("Whatever", systemImage: "pencil")
    }
}

Result:

Result

Sirloin answered 5/8, 2021 at 21:20 Comment(5)
I was hoping that there was a workaround for iOS 14 without resorting to UIKit. Thanks anyway. I really hate that to overcome the deficiencies of SwiftUI I have to use a higher version of the OS itself...Dibbuk
@Dibbuk Yeah, sometimes you just have to use UIKit for certain parts instead. I have a really recent Q&A here which I made actually to create a custom context menu. I do the Introspect with ScrollView thing, and then add a UIContextMenuInteraction with scrollView.subviews.first!.addInteraction(/* interaction delegate instance */). You may find that useful to implement an iOS 14 version of the context menu.Sirloin
Thanks for that! I'll check it out.Dibbuk
I can't set the font to a custom font or color other than redUnfriendly
@Unfriendly Although more customisation is nice, this would be an unusual UX to use something other than "plain" or red as a destructive actionSirloin
M
0

2024

In iOS 17 you can use a .foregroundStyle with multiple arguments, where the first one will be the color for the icon.

Menu {
  HStack { /// This can be a button or whatever you want
    Text("Empty")
    Image(systemName: "circle.fill")
      .foregroundStyle(.red, .primary, .secondary) /// this only works with multiple arguments; a single style would turn into the primary color.
  }
} label: {
  Text("Menu")
}
Michael answered 27/8, 2024 at 11:16 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.