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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:47:10