在SwiftUI中如何实现符合macOS原生风格的sheet弹窗?
macOS SwiftUI sheet 原生按钮样式实现方案
你需要做两处核心调整即可匹配系统原生sheet的按钮样式:
- 给按钮的文本容器设置最大宽度撑满父视图,解决按钮宽度不够的问题
- 给默认操作按钮添加系统默认快捷键标识,触发系统自带的蓝色高亮样式
完整修改后的代码
.sheet(isPresented: $confirmReset) { VStack(alignment: .center, spacing: 16) { Image("sheeticon") .resizable() .frame(width: 72, height: 72) Text("Confirm Reset") .font(.title2) Text("Are you sure you want to reset the generator?") .multilineTextAlignment(.center) .padding(.horizontal, 4) // 按钮组固定间距,匹配系统原生设计规范 VStack(spacing: 10) { Button(action:{ /* Resets some variables first, removed to make this easier to read */ confirmReset = false NSApp.mainWindow?.endSheet(NSApp.keyWindow!) }) { Text("Confirm") .frame(maxWidth: .infinity) // 撑满父容器可用宽度 } .controlSize(.large) .keyboardShortcut(.defaultAction) // 绑定回车默认操作,自动触发系统蓝色高亮样式,兼容macOS11+ Button(action:{ confirmReset = false NSApp.mainWindow?.endSheet(NSApp.keyWindow!) }) { Text("Cancel") .frame(maxWidth: .infinity) // 撑满父容器可用宽度 } .controlSize(.large) .keyboardShortcut(.cancelAction) // 绑定ESC取消操作,符合macOS交互逻辑 } .padding(.horizontal, 16) // 按钮左右留边,避免贴边 } .frame(width: 250, height: 250) .padding(.vertical, 16) // 调整整体内边距,避免内容拥挤 }
修改说明
.frame(maxWidth: .infinity)让按钮的可点击区域撑满父容器的可用宽度,实现满宽按钮效果.keyboardShortcut(.defaultAction)是系统内置的默认操作标识,除了会自动把按钮渲染成蓝色高亮状态,还支持用户按回车键直接触发按钮操作,完美匹配原生弹窗的交互和视觉效果.keyboardShortcut(.cancelAction)对应取消操作,支持用户按ESC键直接关闭弹窗,符合macOS系统交互规范- 按钮组增加左右内边距,避免按钮完全贴合sheet边缘,和原生样式对齐
内容的提问来源于stack exchange,提问作者NinjaCheetah
相关产品推荐
相关产品推荐

