
概览
小伙伴们都知道,弹出 Alert 不能包含文本输入框是 SwiftUI 的阿喀琉斯之踵(Achilles’ Heel) 。当然,这说的有些夸张了。😉
不过,Alert 不能包含 TextField 在某些情况下着实不方便。于是乎,从 SwiftUI 3.0(iOS 15+)开始,Apple 响应码农号召增加了这一功能:

想知道如何实现么?答案超乎寻常的简单!
闲言碎语不再讲,Let’s Go!!!😉
已废弃的旧 Alert
从 SwiftUI 诞生之日起,为了与 UIKit & AppKit 界面功能同步,Apple 创造了 Alert 视图专门用于小窗口的弹出操作:

不过, Alert 使用非常不灵活,其构造器使用起来非常死板:

我们只能按照规定弹出受限布局的窗口,最受诟病的就是其中不能嵌入文本输入框:


新 Alert 介绍
从 SwiftUI 3.0 开始,Apple 终于增强了 Alert 显示界面布局的表现力,我们可以妥妥的加入 TextField 等文本输入视图了:

func alert<S, A, M, T>(
    _ title: S,
    isPresented: Binding<Bool>,
    presenting data: T?, @ViewBuilder actions: (T) -> A, @ViewBuilder message: (T) -> M
) -> some View where S : StringProtocol, A : View, M : View
观察以上新 alert 修改器方法的签名可以发现:它将文本输入和按钮作为一组放在 actions 形参中,而将通知消息文本放在 message 形参中。
在 actions 实参中,我们可以自由组合 TextField、SecureField、Toggle(仅限 MacOS)、按钮等输入控件灵活的适配功能逻辑:
VStack {
    Button(role: .destructive, action: {
        isAlert = true
    }){
        Text("Alert!")
    }
    .alert("一大波僵尸正在靠近", isPresented: $isAlert, actions: {
    	// @ViewBuilder 的闭包,可以自由发挥随意组合视图...
		// SecureField 与 TextField 在 MacOS 中会被忽略
        SecureField("核武器启动密码", text: $pwd)
        TextField("当量", text: $power)
                
        Button(role: .destructive, action: {}){
            Text("核武器攻击!")
        }
        
        // 仅限 MacOS,iOS 中会被忽略
        Toggle("超级模式", isOn: $superMode)
        
        Button("再等等", role: .cancel, action: {})
    }){
        Text("距离大本营还有 \(Int.random(in: 0..<10000)) 公里...")
    }
}
下面是上述代码创建的 Alert 在 iOS 和 MacOS 中的弹出效果:


值得注意的是:MacOS 中的 Alert 不能显示文本输入视图,但可以显示 Toggle 视图(以按钮样式)。
现在,我们在遇到弹出窗口需要输入文本或密码的情况不会再捉襟见肘了,棒棒哒!💯🚀
总结
在本篇博文中,我们讨论了 SwiftUI 中新的 Alert 弹出窗口,使用它我们可以非常轻松的完成文本和密码的输入操作。
- 更多关于 SwiftUI 知识的精彩博文,请移步 开发疑难秒懂百科
 专栏欣赏。
感谢观赏,再会!😉



















