Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sublabel inside SwiftUI Menu Button

I try to create a menu with buttons containing primary and secondary labels like the photo bellow using SwiftUI, so I embed the button and the text (as secondary label) in the VStack, but it's doesn't work. How I can create this view in swiftUI?

enter image description here

The Code

 Menu {
        Section {
            search
        }
        Section {
// The sort button
        Menu  {
            Picker("Sorting options", selection: $sort) {
                ForEach(SortType.allCases, id: \.self) { type in
                    Label("title", systemImage: "chevron.up")
                        .tag(type)
                }
            }
        } label: {
// Here I should embed title and subtitle like the photo but I don't know how.
            Label("Sort By", systemImage: "arrow.up.arrow.down")
        }
        }
    } label: {
        menuLabel
    }
like image 309
Ammar Ahmad Avatar asked Dec 04 '25 10:12

Ammar Ahmad


2 Answers

NEW ANSWER

If you are attempting to get behavior similar to the below, use the content closure of a Button

enter image description here

Menu("HI") {
    Button(action: {}) {
        Text(temperatureType.localizedDescription)
        Text(formatTemperature(sensor.temperature, to: 
    temperatureType.toUnitTemperature()))
    }
}

Here, I am mimicking the new data detectors functionality provided in iOS 16's UITextView Then you can add any of the modifiers you would like


OLD ANSWER

I found a partial way to do this, but it is without the subtitle text smaller and in a foregroundStyle(.secondary) :

enter image description here

Picker(selection: $pointsSortType) {
    Button(PointsSortType.date            .displayName) {}.tag(PointsSortType.date            .rawValue)
    Button(PointsSortType.type            .displayName) {}.tag(PointsSortType.type            .rawValue)
    Button(PointsSortType.submissionStatus.displayName) {}.tag(PointsSortType.submissionStatus.rawValue)
    Button(PointsSortType.duration        .displayName) {}.tag(PointsSortType.duration        .rawValue)
} label: {
    Label {
        Text("""
             Sort By
             Manual
             """)
    } icon: {
        Image(systemName: "arrow.up.arrow.down")
    }
}
.pickerStyle(.menu)

Here, we are using Multi-Line Strings to trick it. I tried messing around with adding multiple Texts in a bunch of Stacks. I even tried type erasing it with AnyView(erasing:), but somehow it's still smarter. I even tried interpolating Text views and adding Text modifiers like Bold, but it overrode that as well.

Sorry for the spaces in between, but that is how I like to format my code.

like image 53
Awesomeplayer165 Avatar answered Dec 07 '25 00:12

Awesomeplayer165


You can achieve this in SwiftUI by adding and extra Text component next to your menu label. For example:

Menu("Sort") {
  Menu {
    Picker("Sort By", selection: $sortBy) {
      ForEach(SortBy.allCases) { sortOption in
        Text(sortOption.rawValue)
          .tag(sortOption)
      }
    }
  } label: {
     Label("Sort By", systemImage: "arrow.up.arrow.down")
     Text(sortBy.rawValue)
  }
}
like image 38
alexortizl Avatar answered Dec 07 '25 00:12

alexortizl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!