iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
移动端没有桌面的窗口机制各种弹窗都是系统功能。目录.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”变成了“info1”符合预期。由于界面和数据完全通过绑定变量交互不用太关心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() }