尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

iOS开发 SwitftUI 13:提示、弹窗、上下文菜单

iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
📅 发布时间:2026/7/5 15:46:48

移动端没有桌面的窗口机制,各种弹窗都是系统功能。

目录

.sheet 弹窗

.fullScreenCover 全屏弹窗

.actionSheet 选项弹窗

.alert 告警

.contextMenu 上下文菜单

汇总代码


.sheet 弹窗

sheet是一种弹窗机制,目前的默认实现是从屏幕下端升起,覆盖屏幕的绝大部分。

sheet属于整个屏幕,虽然把.sheet代码放在最外层符合逻辑,但实际上放在哪一层都没有关系,效果都是一样的。

基本的sheet用法:

@State var b = false @State var str = "info" var body: some View { Form { Button {b = true}label: { Text("打开sheet") } Text(str) } .sheet(isPresented: $b) { Text("关闭") .onTapGesture { str = str + "+1" b = false } } }

sheet需要一个变量来指示是否显示,需要关闭的时候设置变量为false即可。很明显,sheet是当前页面的一部分,只是根据指示显示出来。

初始:

点一下“打开sheet”:

sheet打开,占据屏幕绝大部分。再点一下“关闭”:

“info”变成了“info+1”,符合预期。

由于界面和数据完全通过绑定变量交互,不用太关心sheet对象再次打开时是重新创建还是显示原来的对象,不像桌面程序,要考虑对象的创建和显示/隐藏。

.fullScreenCover 全屏弹窗

只需要简单地把.sheet替换成.FullScreenCover即可,效果:

除了全屏化没别的区别。

.actionSheet 选项弹窗

注意,已经被标记为过时,推荐用confirmationDialog代替。

ActionSheet提供类似菜单的操作,显示方式和前面的两种一样,用一个变量来表示是否显示,选项弹窗的关键代码如下:

.actionSheet(isPresented: $b) { return ActionSheet( title: Text("操作"), message: Text("随便选一个"), buttons: [ .cancel( Text("取消"), action: { str = str + "+cancel" }), .destructive( Text("危险 动作1"), action: { str = str + "+destructive" } ), .default( Text("默认 动作2"), action: { str = str + "+default" } ), ] ) }

效果:

上面的代码在处理动作的时候并没有重置绑定变量b,设置的取消按钮也没有显示,但其实只需要点击弹窗以外的区域弹窗就会关闭,而且,任何一个动作结束都会自动重置绑定变量。

点击空白处取消:

再弹出来一次,点击一个选项:

动作都是正确执行的。

我们创建按钮的时候用了.destructive和.default,这两个是按钮的“角色”,前一个表示是破坏性的,所以系统自动使用红色显示,后一个是默认,系统使用黑色显示。

.alert 告警

写法跟actionSheet差不多:

.alert(isPresented: $bAlert) { return Alert(title: Text("告警") ,message: Text("确定吗?") ,primaryButton: .destructive(Text("确认")){str = str + "+ok"} ,secondaryButton: .default(Text("取消")){str = str + "+canecl"} ) }

效果:

说实话这东西真没有太多自定义的必要,但是从交互设计角度来说,文字应该居中显示。

.contextMenu 上下文菜单

上下文菜单需要通过长按呼出。跟前面的几个不同,不需要变量来指示是否显示,而且显示位置和修饰的对象有关。

下面的代码分别给整体和一个单独的Text设置了上下文菜单:

var body: some View { Form { //。。。。。。 Text(str) .contextMenu { Button("上下文菜单3") { str = str + "+contextMenu3" } Button("上下文菜单4") { str = str + "+contextMenu4" } } } //。。。。。。 .contextMenu { Button("上下文菜单1") { str = str + "+contextMenu1" } Button("上下文菜单2") { str = str + "+contextMenu2" } } }

长按Text的效果:

长按其余部分的效果:

汇总代码

本文的完整代码:

import SwiftUI struct SwiftUIViewPopup: View { @State var bSheet = false @State var bFullScreenCover = false @State var bActionSheet = false @State var bAlert = false @State var str = "info" var body: some View { Form { Button { bSheet = true } label: { Text("打开sheet") } Button { bFullScreenCover = true } label: { Text("打开FullScreenCover") } Button { bActionSheet = true } label: { Text("打开ActionSheet") } Button { bAlert = true } label: { Text("打开Alert") } Text(str) .contextMenu { Button("上下文菜单3") { str = str + "+contextMenu3" } Button("上下文菜单4") { str = str + "+contextMenu4" } } } .sheet(isPresented: $bSheet) { Text("关闭") .onTapGesture { str = str + "+1" bSheet = false } } .fullScreenCover(isPresented: $bFullScreenCover) { Text("关闭") .onTapGesture { str = str + "+a" bFullScreenCover = false } } .actionSheet(isPresented: $bActionSheet) { return ActionSheet( title: Text("操作"), message: Text("随便选一个"), buttons: [ .cancel( Text("取消"), action: { str = str + "+cancel" } ), .destructive( Text("危险 动作1"), action: { str = str + "+destructive" } ), .default( Text("默认 动作2"), action: { str = str + "+default" } ), ] ) } .alert(isPresented: $bAlert) { return Alert( title: Text("告警"), message: Text("确定吗?"), primaryButton: .destructive(Text("确认")) { str = str + "+ok" }, secondaryButton: .default(Text("取消")) { str = str + "+canecl" } ) } .contextMenu { Button("上下文菜单1") { str = str + "+contextMenu1" } Button("上下文菜单2") { str = str + "+contextMenu2" } } } } #Preview { SwiftUIViewPopup() }

相关新闻

  • adsad
  • 【Atlas】如何从官方下载 Apache Atlas 2.4.0 版本?
  • 深度学习图像分割实战:从原理到代码实现

最新新闻

  • Obsidian插件汉化终极指南:如何5分钟让英文插件变中文
  • 5分钟集成方案:为企业级应用添加HTML表格数据导出功能
  • 如何快速上手ComfyUI-WanVideoWrapper:AI视频生成终极指南
  • Password-protection-for-static-pages常见问题解答:解决部署和使用中的8大难题
  • d2s-editor终极指南:5分钟掌握暗黑破坏神2存档编辑技巧
  • 揭秘直播操作可视化神器:input-overlay如何让你的操作变得透明易懂

日新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号