iOS 26中@FocusState变化时SwiftUI工具栏不更新问题
SwiftUI底部工具栏搜索栏焦点状态不更新问题
我尝试在iOS 26的SwiftUI首页视图底部工具栏实现搜索栏,需求是:未搜索时显示Filter按钮,搜索时显示Close按钮。搜索栏是绑定了@FocusState的文本框,但目前文本框获取焦点时视图状态不更新,手动修改isSearching也无变化。
现有代码
import SwiftUI @available(iOS 26.0, *) struct HomeView: View { @State var search: String = "" @FocusState private var isSearching: Bool var body: some View { NavigationStack { HomeFeedView() .toolbar { // Bottom left toolbar - displays when not searching if (!isSearching) { ToolbarItem(placement: .bottomBar) { Button("Filter", systemImage: "line.3.horizontal.decrease") { } } ToolbarSpacer(placement: .bottomBar) } // Bottom center toolbar - displays always but shifts side when in use/not in use ToolbarItem(id: "Search Bar", placement: .bottomBar) { TextField("Search", text: $search) .focused($isSearching) .padding(.horizontal, 10) .submitLabel(.search) .onSubmit { isSearching = false } } // Bottom right toolbar - displays when searching to cancel search if (isSearching) { ToolbarSpacer(placement: .bottomBar) ToolbarItem(placement: .bottomBar) { Button("Close", systemImage: "xmark") { isSearching = false } } } } } } }
解决方案
问题根源
ToolbarItem内部的视图状态变更无法触发工具栏的重新布局,SwiftUI工具栏对条件渲染元素需要更明确的状态传递或布局结构,@FocusState本身功能正常,但在工具栏的条件判断中需要配合显式监听或布局调整。
修复方案
- 用
@State配合@FocusState:通过监听焦点变化同步更新@State变量,确保视图能感知状态变化; - 调整工具栏布局结构:将条件渲染元素放入同一个
ToolbarItemGroup,让SwiftUI准确处理布局更新; - 添加焦点变更监听:通过
.onChange(of: isSearching)触发视图刷新,保证状态变化传递到工具栏。
修复后的代码
import SwiftUI @available(iOS 26.0, *) struct HomeView: View { @State var search: String = "" @FocusState private var isSearching: Bool // 新增@State变量同步焦点状态,确保视图感知变化 @State private var showCloseButton = false var body: some View { NavigationStack { HomeFeedView() .toolbar { ToolbarItemGroup(placement: .bottomBar) { // 未搜索时显示Filter按钮 if !showCloseButton { Button("Filter", systemImage: "line.3.horizontal.decrease") { } ToolbarSpacer() } // 始终显示的搜索栏 TextField("Search", text: $search) .focused($isSearching) .padding(.horizontal, 10) .submitLabel(.search) .onSubmit { isSearching = false showCloseButton = false } // 搜索时显示Close按钮 if showCloseButton { ToolbarSpacer() Button("Close", systemImage: "xmark") { isSearching = false showCloseButton = false search = "" // 可选:清空搜索文本 } } } } // 监听焦点状态变化,同步更新showCloseButton .onChange(of: isSearching) { newValue in showCloseButton = newValue } } } }
额外说明
ToolbarItemGroup让工具栏元素作为整体布局,避免条件渲染导致的布局异常;- 通过
onChange同步焦点状态到@State变量,确保视图正确刷新; - 点击Close按钮时清空搜索文本,可提升用户体验。
内容的提问来源于stack exchange,提问作者karlcridland
相关产品推荐
相关产品推荐

