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

SwiftUI键盘工具栏内嵌ScrollView致导航栏标题卡住问题

问题说明

使用SwiftUI进行iOS开发时,若为键盘配置的toolbar(工具栏,对应ToolbarItem的.keyboard放置位置)内部嵌套ScrollView组件,会触发导航栏标题显示异常:标题会固定卡在屏幕对应位置,无法随导航栏正常联动移动、完成大标题折叠等布局效果。
该问题在Xcode 13.4.1环境下可稳定复现,最小复现代码如下:

struct MyApp: App {
        
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    
    @State var numbers = Array(1...100).map { String($0) }
    
    var body: some View {
        NavigationView {
            List($numbers, id: \.self) { $number in
                TextField("", text: $number)
            }
            .toolbar {
                ToolbarItem(placement: .keyboard) {
                    ScrollView(.horizontal) {
                        HStack {
                            Text("Hello")
                            Text("World")
                        }
                    }
                }
            }
            .navigationTitle("Messed up title")
        }
    }
}

异常效果参考:
导航栏标题固定错位效果

解决方案

该问题属于SwiftUI的系统级布局冲突bug:键盘工具栏内的原生ScrollView会错误干扰导航栏的全局坐标计算,导致标题布局失效,目前有3种可落地的修复方案:

  • 方案1:禁用工具栏内ScrollView的弹性效果
    针对包含在工具栏内的UIScrollView,在视图出现时关闭其弹跳属性,即可消除布局冲突,代码修改如下:
    ToolbarItem(placement: .keyboard) {
        ScrollView(.horizontal) {
            HStack {
                Text("Hello")
                Text("World")
            }
        }
        .onAppear {
            UIScrollView.appearance(whenContainedInInstancesOf: [UIToolbar.self]).bounces = false
        }
    }
    
    该方案仅对UIToolbar内的滚动视图生效,不会影响页面其他位置的ScrollView效果,适配iOS 15及以上系统。
  • 方案2:显式指定ScrollView及内容的固定高度
    给ScrollView和其内部容器设置和系统键盘工具栏一致的固定高度(默认44pt),避免ScrollView动态计算高度时向上传递错误的布局值,代码修改如下:
    ToolbarItem(placement: .keyboard) {
        ScrollView(.horizontal) {
            HStack {
                Text("Hello")
                Text("World")
            }
            .frame(height: 44)
        }
        .frame(height: 44)
    }
    
    该方案兼容性覆盖iOS 14及以上系统,缺点是需要手动匹配不同系统版本下键盘工具栏的默认高度。
  • 方案3:用UIKit封装的滚动组件替代SwiftUI原生ScrollView
    通过UIViewRepresentable包装UIKit的UIScrollView实现横向滚动能力,从根源上避开SwiftUI ScrollView的布局逻辑冲突,适合对适配要求高、需要兼容低版本的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:27:41