You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中弹出并关闭Alert后,Toolbar Done按钮消失问题求助

SwiftUI键盘Toolbar Done按钮在Alert关闭后消失的解决办法

问题原因

这个问题出在Toolbar的作用域上:你把键盘Toolbar附加在内部的表单VStack上,当Alert弹出并关闭后,该VStack的视图状态会被重置,导致键盘Toolbar无法重新关联到文本字段,最终出现消失的情况。

解决方案一:将Toolbar移到外层NavigationView层级

把Toolbar直接附加到NavigationView的直接子视图上(也就是ZStack),因为NavigationView作为页面容器,生命周期更稳定,不会因为Alert的弹出关闭而破坏Toolbar与键盘的关联。

修改后的完整代码:

var body: some View {
    NavigationView {
        ZStack {
            AppColors.primaryColor
                .ignoresSafeArea(.all)
            
            VStack {
                NavigationViewWithTitleInCenter(title: "Feedback", backButtonAction: {
                    presentationMode.wrappedValue.dismiss()
                    print("Back button tapped!")
                })
                
                Spacer()
                
                VStack {
                    TitleWithTextfield(placeholder: "Enter Name", text: $name)
                    TitleWithTextfield(placeholder: "Enter Email", text: $email)
                    TitleWithTextfield(placeholder: "Enter Subject", text: $subject)
                    TitleWithTextView(placeholder: "Enter Message", text: $description)
                    
                    PrimaryButton(title: "Submit").onTapGesture {
                        self.didTapSubmit()
                    }
                }
                
                Spacer()
            }
            .blur(radius: isLoading ? 1 : 0)
            .loadingOverlay(isLoading: isLoading)
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text("Message"), message: Text("\(alertMessage)"), dismissButton: .default(Text("OK")))
        }
        // 把Toolbar移到这里,关联到NavigationView的子视图
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                Spacer()
                Button("Done") {
                    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                }
                .foregroundColor(.blue)
            }
        }
    }
}

解决方案二:给内部VStack添加稳定ID

如果需要保留Toolbar在内部表单VStack上,可以给该VStack添加一个固定的id,让SwiftUI识别这是同一个视图,避免Alert关闭后重置Toolbar配置:

VStack {
    TitleWithTextfield(placeholder: "Enter Name", text: $name)
    TitleWithTextfield(placeholder: "Enter Email", text: $email)
    TitleWithTextfield(placeholder: "Enter Subject", text: $subject)
    TitleWithTextView(placeholder: "Enter Message", text: $description)
    
    PrimaryButton(title: "Submit").onTapGesture {
        self.didTapSubmit()
    }
}
.id("feedback-form-container") // 添加固定ID
.toolbar {
    ToolbarItemGroup(placement: .keyboard) {
        Spacer()
        Button("Done") {
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
        .foregroundColor(.blue)
    }
}

原理说明

  • 方案一利用了NavigationView的稳定生命周期,确保Toolbar始终与页面的键盘状态绑定,不会因Alert的临时弹窗被销毁。
  • 方案二通过固定视图ID,让SwiftUI在视图刷新时保留原有的Toolbar配置,避免重新创建视图时丢失键盘关联。

内容的提问来源于stack exchange,提问作者Raja Talha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:43:15