SwiftUI中如何为macOS创建带文本字段的提醒弹窗(可借助AppKit)
可以实现,根据项目支持的最低macOS系统版本,可选择以下两种方案:
方案1:纯SwiftUI原生实现(适用macOS 12.0及以上)
macOS 12 开始系统内置的SwiftUI alert修饰符已经原生支持内嵌文本输入控件,无需桥接AppKit,调用后会展示和系统样式完全一致的提醒弹窗,是优先推荐的实现方式。
示例代码:
import SwiftUI struct DemoView: View { @State private var showInputAlert = false @State private var userInput = "" var body: some View { Button("弹出带输入框的提醒") { showInputAlert = true } .alert("操作提示", isPresented: $showInputAlert) { TextField("请输入内容", text: $userInput) // 如需密码输入场景,替换为SecureField即可 // SecureField("请输入密码", text: $userInput) Button("确认") { // 在此处编写输入内容的后续处理逻辑 print("用户输入结果:\(userInput)") } Button("取消", role: .cancel) { userInput = "" } } message: { Text("请在下方输入框填写需要提交的内容") } } }
方案2:AppKit桥接实现(兼容全版本macOS)
如果项目需要兼容macOS 12以下的系统版本,可以通过桥接AppKit的NSAlert实现,封装为可复用的ViewModifier后调用方式和原生API几乎一致,还可以灵活自定义输入框的属性。
首先封装可复用组件:
import SwiftUI import AppKit struct MacInputAlertModifier: ViewModifier { @Binding var isPresented: Bool let title: String let message: String let placeholder: String let defaultValue: String let onConfirm: (String) -> Void func body(content: Content) -> some View { content .onChange(of: isPresented) { isShow in guard isShow else { return } let alert = NSAlert() alert.messageText = title alert.informativeText = message alert.addButton(withTitle: "确认") alert.addButton(withTitle: "取消") // 配置输入框 let inputField = NSTextField(frame: NSRect(x: 0, y: 0, width: 280, height: 24)) inputField.placeholderString = placeholder inputField.stringValue = defaultValue alert.accessoryView = inputField // 前置应用窗口并弹出模态弹窗 NSApp.activate(ignoringOtherApps: true) let response = alert.runModal() if response == .alertFirstButtonReturn { onConfirm(inputField.stringValue) } isPresented = false } } } extension View { func macInputAlert( isPresented: Binding<Bool>, title: String, message: String = "", placeholder: String = "", defaultValue: String = "", onConfirm: @escaping (String) -> Void ) -> some View { self.modifier(MacInputAlertModifier( isPresented: isPresented, title: title, message: message, placeholder: placeholder, defaultValue: defaultValue, onConfirm: onConfirm )) } }
调用示例:
struct DemoView: View { @State private var showInputAlert = false var body: some View { Button("弹出兼容版输入弹窗") { showInputAlert = true } .macInputAlert( isPresented: $showInputAlert, title: "重命名", message: "请输入新的文件名称", placeholder: "例如:工作文档.md", defaultValue: "未命名.md" ) { newName in print("重命名结果:\(newName)") } } }
注意事项
- iOS端基于UIKit的实现依赖
UIAlertController类,该类在macOS平台不存在,无法直接复用 - 原生SwiftUI方案在macOS 11及以下系统会触发编译错误,部署目标低于12.0时必须使用桥接方案
- 桥接方案中可根据需求将
NSTextField替换为NSSecureTextField实现密码输入,也可添加输入校验逻辑限制输入内容格式
内容的提问来源于stack exchange,提问作者MasterMind
相关产品推荐
相关产品推荐

