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

SwiftUI中含SearchBar的列表下拉触发导航栏警告问题求助

解决NavigationStack中带SearchBar的列表下拉触发导航栏断言警告问题

问题描述

在使用SwiftUI的NavigationStack时,若页面包含带SearchBar的列表,下拉列表操作会触发Xcode弹出如下断言警告:

[Assert] What changed the navigation bar bounds size to something unexpected during the animation if it wasn't a showsScopeBar change?

复现代码如下:

enum Route: Hashable {
    case list
}

class ExampleCoordinator: ObservableObject {
    @Published var path = NavigationPath()

    func push(_ route: Route) {
        path.append(route)
    }
}

struct ContentView: View {
    @StateObject private var coordinator = ExampleCoordinator()
    var body: some View {
        ZStack {
            NavigationStack(path: $coordinator.path) {
                VStack(spacing: 40) {
                    Button("Test") {
                        coordinator.push(.list)
                    }
                }
                .navigationTitle("Hello")
                .navigationDestination(for: Route.self) { route in
                    switch route {
                    case .list:
                        ListView()
                    }
                }
            }
        }
    }
}

struct ListView: View {
    @State private var searchableText = ""
    let array: [Int] = {
        var array = [Int]()

        for value in 0...99 {
            array.append(value)
        }
        return array
    }()

    var body: some View {
        list
            .navigationBarTitleDisplayMode(.inline)
            .searchable(text: $searchableText, placement: .toolbar)
            .autocorrectionDisabled(true)
            .scrollDismissesKeyboard(.immediately)
    }

    private var list: some View {
        List {
            ForEach(array, id: \.description) { number in
                Text(number.description)
                    .id(number)
            }
        }
        .listStyle(.plain)
    }
}

问题演示:
下拉触发警告的演示

解决方法

目前有两种可靠的修复方式:

方法一:调整SearchBar的放置位置

将searchable修饰符的placement参数从.toolbar改为.navigationBarDrawer,让搜索栏嵌入导航栏抽屉而非直接放在工具栏中,避免布局冲突:

struct ListView: View {
    // ... 其他代码不变 ...
    var body: some View {
        list
            .navigationBarTitleDisplayMode(.inline)
            // 修改placement参数
            .searchable(text: $searchableText, placement: .navigationBarDrawer)
            .autocorrectionDisabled(true)
            .scrollDismissesKeyboard(.immediately)
    }
}

方法二:添加空Toolbar稳定导航栏布局

在ListView中添加一个空的Toolbar,强制导航栏保持稳定的布局结构,避免下拉时的边界尺寸异常:

struct ListView: View {
    // ... 其他代码不变 ...
    var body: some View {
        list
            .navigationBarTitleDisplayMode(.inline)
            .searchable(text: $searchableText, placement: .toolbar)
            .autocorrectionDisabled(true)
            .scrollDismissesKeyboard(.immediately)
            // 添加空Toolbar
            .toolbar {
                ToolbarItem(placement: .principal) {}
            }
    }
}

说明

该问题属于SwiftUI框架的布局兼容性问题,上述两种方法均能避免导航栏在列表下拉动画过程中出现异常尺寸变化,从而消除断言警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:15:12