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

iOS16.4/SwiftUI4中搜索栏与ScrollView的动画卡顿问题

SwiftUI搜索栏与键盘动画重叠卡顿问题解决方案

我有一个包含搜索栏和ScrollView的简单页面,点击搜索栏时,键盘上推的动画会和搜索栏重叠,还出现卡顿现象,演示如下:
键盘与搜索栏重叠卡顿

我的代码如下:

struct CustomTabBar: View {
    @State var searchText = ""
    var data = [1,2,3,4,5,6,7,8,9,10]
    var body: some View {
        NavigationStack {
            ScrollView(.vertical) {
                ForEach(data, id: \.self) { d in
                    box
                }
            }
            .navigationTitle("Search")
            .searchable(text: $searchText)
        }
    }
    
    var box: some View {
        Rectangle()
            .frame(width: 75, height: 50)
            .cornerRadius(10)
    }
}

解决方案

这个问题源于ScrollView的键盘布局响应逻辑和searchable的默认动画冲突,以下是两种可行的解决方式:

  • 方式一:固定导航栏并让ScrollView忽略键盘安全区域
    通过navigationBarTitleDisplayMode(.inline)固定导航栏样式,避免布局跳动;再用ignoresSafeArea(.keyboard)让ScrollView不随键盘上推,彻底解决重叠问题:

    struct CustomTabBar: View {
        @State var searchText = ""
        var data = [1,2,3,4,5,6,7,8,9,10]
        var body: some View {
            NavigationStack {
                ScrollView(.vertical) {
                    ForEach(data, id: \.self) { d in
                        box
                    }
                }
                .navigationTitle("Search")
                .navigationBarTitleDisplayMode(.inline)
                .searchable(text: $searchText)
                .ignoresSafeArea(.keyboard)
            }
        }
        
        var box: some View {
            Rectangle()
                .frame(width: 75, height: 50)
                .cornerRadius(10)
        }
    }
    
  • 方式二:用ScrollViewReader优化滚动动画
    如果需要保持ScrollView随键盘上推的交互,使用ScrollViewReader监听搜索状态变化,自动滚动到顶部,避免布局重叠卡顿:

    struct CustomTabBar: View {
        @State var searchText = ""
        var data = [1,2,3,4,5,6,7,8,9,10]
        var body: some View {
            NavigationStack {
                ScrollViewReader { proxy in
                    ScrollView(.vertical) {
                        ForEach(data, id: \.self) { d in
                            box
                                .id(d)
                        }
                    }
                    .navigationTitle("Search")
                    .searchable(text: $searchText)
                    .onChange(of: searchText) { _ in
                        proxy.scrollTo(1, anchor: .top)
                    }
                }
            }
        }
        
        var box: some View {
            Rectangle()
                .frame(width: 75, height: 50)
                .cornerRadius(10)
        }
    }
    

另外,建议检查项目使用的iOS SDK版本,iOS 16及以上系统对searchable的布局逻辑有优化,升级到较新的SDK也能缓解这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:27:39