SwiftUI中Menu和ControlGroup的使用

本篇文章主要介绍一下Menu组件和ControlGroup组件的使用。Menu组件是在iOS 14(tvOS 17)推出的一个组件,点击后提供一个可选择的操作列表。ControlGroup组件是一个容器视图,以视觉上适当的方式为给定的上下文显示语义相关的控件,这意味着ControlGroup的外观将取决于视图的上下文。

Menu的使用

Menu组件提供了一个可选择的操作列表。比较常用的初始化方法如下:

init(
    @ViewBuilder content: () -> Content,
    @ViewBuilder label: () -> Label
)

label:该闭包提供一个Menu自身显示的视图内容。
content:该闭包提供点击Menu组件后要显示的视图内容。

下面先看一个使用示例:
在这里插入图片描述

var body: some View {
  Menu("Tap me") {
    // Menu 1
    Text("Menu 1")
      .onTapGesture {
        print("Menu 1 clicked")
      }

    // Menu 2
    Button("Menu 2") {
      print("Menu 2 clicked")
    }

    // Menu 3
    Button(action: {
      print("Menu 3 clicked")
    }, label: {
      Label("Menu 3", systemImage: "heart.fill")
    })

    // Menu 4
    Button(action: {
      print("Menu 4 clicked")
    }, label: {
      Text("Menu 4")
        .font(.largeTitle)
        .foregroundColor(.red)
      Image(systemName: "trash")
      Image(systemName: "magnifyingglass")
    })

    // Menu 5
    Menu("Copy") {
      Button("Copy", action: {})
      Button("Copy Formatted", action: {})
      Button("Copy Library Path", action: {})
    }
  }
}

上面代码中,我们创建了一个menu,传入了一个title,并在content闭包内添加了一些组件。Menu的初始化方法很多,这里不过多的介绍了,我们主要看一下content闭包的内容。

content闭包内:

  • menu1是一个Text组件,并且添加了tap手势,不过事实证明,它只会显示出来,并且文字暗灰色,无法点击,应该是被系统disabled了,所以menu1这种无效。
  • menu2是一个Button组件,仅仅设置了一个title和点击事件。title显示正常,点击事件正常。
  • menu3是一个Button组件,不过其显示内容通过Label组件设置了,并带了一个图片。titleimage显示都正常,点击事件也正常。
  • menu4是一个Button组件,显示内容没有采用Label组件,而是Text加上Image组合,事实证明,TextImage都显示正常,多余的Image无法显示,点击事件正常。
  • menu5是一个Menu组件,这属于嵌套了,一切显示都正常。

之前有一篇文章里面也提及到了MenuPicker的配合使用,感兴趣的朋友可以去看看。SwiftUI中普通Picker的用法

Menu也可以放到导航栏上面,弹出的内容不会超出屏幕。

  var body: some View {
    NavigationStack {
      VStack {
        Color.orange.ignoresSafeArea()
      }
      .toolbar(content: {
        ToolbarItem(placement: .topBarTrailing) {
          Menu("Copy") {
      		Button("Copy", action: {})
      		Button("Copy Formatted", action: {})
      		Button("Copy Library Path", action: {})
      	  }
        }
      })
    }
  }

ControlGroup的使用

ControlGroup视图是一个简单的容器视图,它接受ViewBuilder闭包,并根据当前环境显示它。ControlGroup视图是iOS 14(tvOS 17)推出的一个组件。
让我们看看如何使用它。

ControlGroup {
  Button(action: {}) {
    Label("Decrease", systemImage: "minus")
  }

  Button(action: {}) {
    Label("Increase", systemImage: "plus")
  }
}

在这里插入图片描述
正如在上面的例子中看到的,我们只是在ControlGroup视图中放了两个按钮,就像我们在VStackHStack中做的那样。但是ControlGroup不是使用垂直或水平轴来布局视图,而是根据视图的上下文添加合适的样式。

样式设置

通过controlGroupStyle修饰符可以添加一些样式,一些主要的样式有:

  • AutomaticControlGroupStyle:可简写为.automatic
  • NavigationControlGroupStyle:可简写为.navigation

具体显示成什么样还得看用在哪里了,比如下面的Demo:
可简写为
上面的代码中,先在界面中间显示了两个,然后在导航栏上加了两个,具体见代码。

自定义样式

我们可以创建一个符合ControlGroupStyle协议的类型,并实现一个名为makeBody的必需函数。

下面代码创建了一个竖向排列的样式:

struct VerticalControlGroupStyle: ControlGroupStyle {
  func makeBody(configuration: Configuration) -> some View {
    VStack {
        configuration.content
    }
    .foregroundColor(.red)
  }
}

在这里插入图片描述

下面这个在ControlGroup组件中添加了一个Title:

struct ControlGroupWithTitle: ControlGroupStyle {
    let title: LocalizedStringKey

    func makeBody(configuration: Configuration) -> some View {
        VStack {
            Text(title)
                .font(.title)
            HStack {
                configuration.content
            }
        }
    }
}

在这里插入图片描述

Menu和ControlGroup的混合使用

MenuControlGroup也是可以放在一起使用的。

下面代码中将ControlGroup放在Menu中使用,具体看看效果吧。

struct MenuAndControlGroupDemo: View {
  var body: some View {
    VStack {
      Menu("Action 1") {
        Button("Menu 1", action: {})
        Button("Menu 2", action: {})
        ControlGroup {
          Button(action: {}) {
            Label("Decrease", systemImage: "minus")
          }

          Button(action: {}) {
            Label("Increase", systemImage: "plus")
          }
        }
      }

      Spacer()
        .frame(height: 60)

      Menu("Action 2") {
        Button("Menu 1", action: {})
        Button("Menu 2", action: {})
        ControlGroup {
          Button(action: {}) {
            Text("Decrease")
          }

          Button(action: {}) {
            Text("Increase")
          }
        }
      }
    }
    .padding()
  }
}

在这里插入图片描述
下面将Menu放到ControlGroup中试试:

  var body: some View {
    VStack {
      ControlGroup {
        Button(action: {}) {
          Text("Decrease")
        }

        Button(action: {}) {
          Text("Increase")
        }

        Menu("Action 1") {
          Button("Menu 1", action: {})
          Button("Menu 2", action: {})
        }
      }
      .controlGroupStyle(.navigation)
    }
    .padding()
  }

在这里插入图片描述
这里需要设置.controlGroupStyle(.navigation)才能点击。

如果将整个组合组件放到导航栏里面,那么不设置.controlGroupStyle(.navigation),也是可以点击的。

  var body: some View {
    NavigationStack {
      VStack {
        Color.orange.ignoresSafeArea()
      }
      .toolbar(content: {
        ToolbarItem(placement: .topBarTrailing) {
          ControlGroup {
            Button(action: {}) {
              Text("Decrease")
            }

            Button(action: {}) {
              Text("Increase")
            }

            Menu("Action 1") {
              Button("Menu 1", action: {})
              Button("Menu 2", action: {})
            }
          }
        }
      })
    }
  }

在这里插入图片描述

写在最后

本文主要介绍了MenuControlGroup的基本使用,都是一些小组件,而且在显示的时候系统也会根据不同平台的上下文语义来决定怎么显示,非常好用,如果用在自己的App中,是不是会增加用户体验呢?

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683379.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

钢基础知识介绍

钢铁是一种铁碳合金,含有一定量的碳和其他合金元素,如硅、锰等。而钢材则是经过加工处理后的钢铁材料,具有更高的强度、硬度、塑性和韧性。钢铁的硬度、强度和耐磨性相对较低,而钢材经过加工处理后,其硬度、强度和耐磨…

训练营第二十七天 | 491.递增子序列46.全排列47.全排列 II332.重新安排行程51. N皇后

491.递增子序列 力扣题目链接(opens new window) 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 说明: …

企业(园区)智慧能源双碳平台解决方案

园区作为工业企业集聚区,在提供了大量基础设施和公共服务的同时也成为了碳排放的主要源头。工业园区的耗能约占全社会总耗能的69%,碳排放占全国总排放约31%。工业园区节能、减耗、提质、减碳工作的落实,是我国实现碳达峰碳中和目标的必然要求…

关系代数与规范化

本文是根据自己的理解,结合实践整理所得,有兴趣的可以参考学习。

P3. 创建个人中心页面

P3. 创建个人中心页面 0 概述Tips1 个人中心页面1.1 创建 Bot 表及 pojo, mapper1.2 实现 Bot 增删改查的 API1.3 实现个人中心页面前端 0 概述 主要介绍了一下添加一个表(类),及其CRUD的前端和后端的实现方式,介绍的是通用的方法。 后端的CRUD很好写&am…

TCP/IP协议介绍——三次握手四次挥手

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议…

Capture One Pro 23:专业 Raw 图像处理的卓越之选

在当今的数字摄影时代,拥有一款强大的图像处理软件至关重要。而 Capture One Pro 23 for Mac/Win 无疑是其中的佼佼者,为摄影师和图像爱好者带来了前所未有的体验。 Capture One Pro 23 以其出色的 Raw 图像处理能力而闻名。它能够精准地解析和处理各种…

Priority_queue

一、priority_queue的介绍和使用 1.1 priority_queue的介绍 1.优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。 2.优先队列类似于堆, 在堆中可以随时插入元素, 并且只能检索最大堆…

React中使用 ts 后,craco库配置别名时需要注意什么?

文章目录 前言编译报错如下解决方式总结 前言 我们都知道craco库可以用来覆盖react配置,如设置别名等。但是在项目使用 Typescript 后,我们需要额外配置,否则会造成编译报错。 详细craco配置可以查看之前文章: 项目初始化与配置…

SpringBoot:SpringBoot中使用Redisson实现分布式锁

一、前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。 刚好项目中需要使用到分布式锁,记录一下Redisson是如何使用分布式…

PHP 页面报错Warning</b>: Cannot modify header information - headers already sent by

先给出解决方案再解释,如果急着用就不用看解释了。 解决方案一:保存php文件编码为utf-8无BOM码,具体操作可以用notepad等编辑器完成,把 sesstion_start() 放在文档所有输出(包括html标签和php的输出语句,具…

场外个股期权标的有哪些?

今天带你了解场外个股期权标的有哪些?场外个股期权是一种金融衍生品,它不在交易所内进行交割,而是在交易所以外的场所进行交易的股票期权合约。 场外个股期权标的有哪些? 场外个股期权的标的通常包括A股市场上的融资融券标的&…

掌握Django文件处理:一步步构建上传功能

创建模型 首先先进入我们的testsite项目下,打开members/models.py文件,先添加我们保存文件的数据模型: class Document(models.Model):name models.CharField(max_length255)file models.FileField(upload_touploads/) # uploads/ 是文件…

批量提取 Word 文档中的全部图片

步骤 1、打开 WinRAR 任选一个现成的压缩包双击打开 WinRAR ,或从开始菜单打开 WinRAR 2、直接把要提取图片的 Word 文档拖入 WinRAR 菜单区域 1 → 2 → 3,WinRAR 资源管理目录中的 media 就是该 Word 文档所要提取的全部图片所在文件夹 按住&#x…

【Vue】异步更新 $nextTick

文章目录 一、引出问题二、解决方案三、代码实现 一、引出问题 需求 编辑标题, 编辑框自动聚焦 点击编辑,显示编辑框让编辑框,立刻获取焦点 即下图上面结构隐藏,下面结构显示,并且显示的时候让它自动聚焦。 代码如下 问题 “…

Vue3:eachars 折线图 数据不联动 和 tooltip: trigger: ‘axis‘ 不生效,不提示数据

问题1: 点击折线图的头部数据(Email、UnionAds等) 下面数据线不联动问题 问题2:下图是没有提示数据的Demo 这是echars官网的提示数据图 3.解决办法 (1)检查是否设置:trigger:axi…

SELinux深度解析:安全增强型Linux的探索与应用(下)

🐇明明跟你说过:个人主页 🏅个人专栏:《Linux :从菜鸟到飞鸟的逆袭》🏅 🔖行路有良友,便是天堂🔖 目录 一、SELinux的工作机制 1、SELinux的三种状态:Pe…

在k8s中部署Kafka高可用集群超详细讲解

🐇明明跟你说过:个人主页 🏅个人专栏:《数据流专家:Kafka探索》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Kafka简介 2、为什么在Kubernetes中部署Kafka 二、…

决策树Decision Tree

目录 一、介绍发展优点缺点基本原理 二、熵1、熵2、条件熵3、信息增益4、信息增益率 三、基尼系数四、ID3算法1、建树过程2、优点3、缺点 五、C4.51、二分法处理连续变量1、流程:2、示例 2、缺点 六、CART1、连续数据处理2、离散数据处理3、CART回归原理1、均方误差…

医学编码系统说明

简介 流程说明 登录系统 在浏览器中访问FNEHR的站点,输入医院编号、用户和密码,选择“Other”,点击“Login”按钮,登录系统: 登录后,在左边显示系统的菜单: 系统设置 医院设置 点击左侧的“Acc…