You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何自定义嵌套Menu菜单项及按钮的外观?

解决方案

问题原因

SwiftUI 内置 Menu 展开后的子项默认遵循系统菜单样式规范,你直接给内部 label 添加的 background 修饰符会被系统预设的列表单元格样式覆盖,因此无法正常渲染。

适配代码(iOS 15+)

import SwiftUI

struct ContentView: View {
    var body: some View {
        DropDownMenu()
    }
}

struct DropDownMenu: View {
  private let categories: [Category]
  @State private var selectedSubcategory = "Select a category"
  
  let letters = ["a", "b", "c"]
  
  init() {
    self.categories = [Category(name: "letters", subcategories: letters)]
  }
  
    var body: some View {
      Menu {
        Menu {
          Button {
            selectedSubcategory = categories[0].subcategories[0]
          } label: {
            Text(categories[0].subcategories[0])
              .foregroundColor(.white)
              .frame(maxWidth: .infinity, alignment: .leading)
              .contentShape(Rectangle())
          }
          .listRowBackground(Color.blue)
          
          Button {
            selectedSubcategory = categories[0].subcategories[1]
          } label: {
            Text(categories[0].subcategories[1])
              .foregroundColor(.white)
              .frame(maxWidth: .infinity, alignment: .leading)
              .contentShape(Rectangle())
          }
          .listRowBackground(Color.blue)
          
          Button {
            selectedSubcategory = categories[0].subcategories[2]
          } label: {
            Text(categories[0].subcategories[2])
              .foregroundColor(.white)
              .frame(maxWidth: .infinity, alignment: .leading)
              .contentShape(Rectangle())
          }
          .listRowBackground(Color.blue)
        } label: {
          Text(categories[0].name)
            .foregroundColor(.white)
            .frame(maxWidth: .infinity, alignment: .leading)
            .contentShape(Rectangle())
        }
        .listRowBackground(Color.blue)
      } label: {
        Text(selectedSubcategory)
          .foregroundColor(.black)
          .background(Color.blue)
      }
    }
}

struct Category: Hashable {
  var id = UUID()
  var name: String
  var subcategories: [String]
}

核心修改说明

  • listRowBackground(Color.blue):Menu 展开后的子项本质是列表单元格,该修饰符直接设置单元格的背景色,不会被系统样式覆盖
  • frame(maxWidth: .infinity, alignment: .leading):让文本内容撑满整个单元格宽度,避免背景仅显示在窄小的文本区域
  • contentShape(Rectangle()):扩大点击响应区域,保证点击单元格任意位置都能触发对应操作
    如果需要适配 iOS 15 以下的系统版本,可以自定义弹出视图替代系统内置 Menu 组件实现同等效果。
    效果演示:
    效果演示图

内容的提问来源于stack exchange,提问作者cbusch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:54:06