SwiftUI中Toolbar搜索栏展开/收起动画失效问题求助
SwiftUI搜索栏左右平滑展开收起动画实现
你原来的代码用if-else切换搜索按钮和搜索栏视图,导致动画是生硬的视图替换,要实现左右平滑展开/收起,得改成基于宽度变化的动画过渡,同时控制内部元素的显示状态。以下是修改后的代码:
ToolbarItem(placement: .automatic) { HStack(spacing: 8) { // 搜索图标始终显示 Image(systemName: "magnifyingglass") // 搜索输入框:仅在展开时显示,配合动画渐显 if showSearchBar { TextField("search from menu", text: $txtSearch) .transition(.opacity.combined(with: .slide)) } // 关闭按钮:仅在展开时显示 if showSearchBar { Button { withAnimation(.easeInOut(duration: 0.3)) { showSearchBar.toggle() txtSearch = "" // 可选:清空搜索内容 } } label: { Image(systemName: "xmark") } .transition(.opacity.combined(with: .scale)) } } // 核心:动画控制宽度变化,收起时宽度等于按钮尺寸(40),展开时300 .frame(width: showSearchBar ? 300 : 40, height: 40) .padding(showSearchBar ? 10 : 0) .background(Color.white) .cornerRadius(20) // 点击非关闭按钮区域时展开搜索栏 .onTapGesture { guard !showSearchBar else { return } withAnimation(.easeInOut(duration: 0.3)) { showSearchBar.toggle() } } }
关键改动说明:
- 去掉原来的
if-else视图切换逻辑,用单个HStack承载所有元素,通过宽度动画实现展开/收起的拉伸效果 - 搜索输入框和关闭按钮用
if showSearchBar控制显示,搭配transition让它们在展开时平滑出现 - 外层
frame宽度绑定showSearchBar状态,从40(收起时的按钮大小)动画过渡到300(展开后的搜索栏宽度) - 给容器添加
onTapGesture,点击搜索图标区域也能展开搜索栏,体验更流畅 - 明确指定动画时长和曲线(
.easeInOut(duration: 0.3)),让动画节奏更贴合预期效果
如果想要更贴近参考视频的"滑入"质感,还可以结合offset动画微调,但上面的方案已经是最简洁的平滑左右展开实现方式。
内容的提问来源于stack exchange,提问作者dhaval123
相关产品推荐
相关产品推荐

