SwiftUI开发:iOS键盘工具栏出现两个Done按钮问题求助
问题:SwiftUI键盘工具栏出现重复Done按钮,移除后无法隐藏键盘
我正在学习SwiftUI教程,尝试通过.focus()修饰符和布尔值实现点击Done按钮隐藏键盘,但遇到两个问题:
- 键盘工具栏显示两个Done按钮,但我只添加了一个自定义按钮
- 移除自定义按钮后,工具栏不再显示Done按钮,无法隐藏键盘
已在预览和iPhone模拟器测试,未在物理设备测试。
截图

我的代码
// ContentView.swift // WeSplit import SwiftUI struct ContentView: View { @State private var checkAmount = 0.0 @State private var numberOfPeople = 2 @State private var tipPercentage = 20 @FocusState private var amountIsFocused: Bool let tipPercentages = [10, 15, 20, 25, 0] //For Total cost + tip var grandTotal: Double{ let tipSelection = Double(tipPercentage) let tipValue = checkAmount / 100 * tipSelection let grandTotal = checkAmount + tipValue return grandTotal } //For individual share var totalPerPerson: Double{ let peopleCount = Double(numberOfPeople + 2) let amountPerPerson = grandTotal / peopleCount return amountPerPerson } var body: some View { NavigationView { Form{ Section{ TextField("Amount: ", value: $checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD")) .keyboardType(.decimalPad) .focused($amountIsFocused) Picker("Number of people", selection: $numberOfPeople){ ForEach(2..<100){ Text("\($0) people") } } } Section{ Picker("Tip Percentage", selection: $tipPercentage){ ForEach(tipPercentages, id:\.self){ Text($0, format: .percent) } }.pickerStyle(.segmented) }header: { Text("How much tip do you want to leave?") } //Grand Total Section{ Text(grandTotal, format:.currency(code: Locale.current.currencyCode ?? "USD")) }header: { Text("Total Cost + Tip") } //Showing each person's share Section{ Text(totalPerPerson, format: .currency(code: Locale.current.currencyCode ?? "USD")) }header: { Text("Amount Per Person") }.navigationTitle("WeSplit") .toolbar(){ ToolbarItemGroup(placement: .keyboard){ Button("Done"){ amountIsFocused = false } } } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
解决方案
问题根源是你把.navigationTitle()和.toolbar()修饰符添加到了最后一个Section上,而非Form或NavigationView层级。SwiftUI会为每个Section单独生成工具栏,导致重复出现Done按钮。
修复步骤
- 将
.navigationTitle("WeSplit")和.toolbar()从最后一个Section移到Form的末尾(或NavigationView内部的根视图上) - 确保工具栏修饰符只作用于整个导航视图的根层级,避免重复生成
修改后的核心代码
var body: some View { NavigationView { Form{ // 所有原有Section内容保持不变 } .navigationTitle("WeSplit") // 移至Form层级 .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("Done") { amountIsFocused = false } } } // 移至Form层级 } }
补充说明
.decimalPad类型的键盘默认没有自带Done按钮,必须手动添加工具栏按钮才能实现隐藏功能- 若将工具栏修饰符加在Section上,每个包含可聚焦控件(如TextField)的Section都会生成独立工具栏,导致按钮重复
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

