SwiftUI双轴滚动ScrollView嵌套LazyStack布局错乱如何解决
SwiftUI双轴ScrollView电子表格布局错乱问题
问题描述
在面向iPhone、iPad、Mac的SwiftUI跨平台项目中,使用同时开启.horizontal和.vertical双轴滚动的ScrollView实现类电子表格布局。ScrollView内部嵌套配置了pinnedViews: [.sectionHeaders, .sectionFooters]的LazyVStack,其中区头、区尾、内容单元格均各自包裹在LazyHStack中;采用懒加载堆栈是为了适配行列数据量增长时的性能需求,但双轴同时滚动时ScrollView会出现严重的布局错乱问题。
已尝试的无效方案
- 自研懒加载水平堆栈,仅渲染可视范围内的单元格,动态计算设置前后内边距,未解决问题
- 引入Introspect for SwiftUI库,为macOS端设置
usesPredominantAxisScrolling属性、为iOS端设置isDirectionalLockEnabled属性,效果不符合预期 - 实现手动滚动轴锁定逻辑:某一轴滚动时锁定另一轴,该方案在iOS端运行正常,但macOS端因缺少
NSScrollViewDelegate回调、滚动事件通过NotificationCenter传递导致性能极差,无法投入使用
效果展示
提供iOS、macOS端的异常效果截图与录屏供参考:
- iOS端异常截图:

- macOS端异常截图:

- iOS端异常效果录屏
- macOS端异常效果录屏
复现代码
新建Multiplatform类型的SwiftUI项目后,将以下代码粘贴至ContentView.swift文件即可复现问题:
import SwiftUI let numberOfColums: Int = 150 let numberOfRows: Int = 350 struct ContentView: View { var items: [[Item]] = { var items: [[Item]] = [[]] for rowIndex in 0..<numberOfRows { var row: [Item] = [] for columnIndex in 0..<numberOfColums { row.append(Item(column: columnIndex, row: rowIndex)) } items.append(row) } return items }() var body: some View { Group { ScrollView([.horizontal, .vertical]) { LazyVStack(alignment: .leading, spacing: 1, pinnedViews: [.sectionHeaders, .sectionFooters]) { Section(header: Header()) { ForEach(0..<items.count, id: \.self) { rowIndex in let row = items[rowIndex] LazyHStack(spacing: 1) { ForEach(0..<row.count, id: \.self) { columnIndex in Text("\(columnIndex):\(rowIndex)") .frame(width: 100) .padding() .background(Color.gray.opacity(0.2)) } } } } } } .edgesIgnoringSafeArea([.top]) } .padding(.top, 1) } } struct Header: View { var body: some View { LazyHStack(spacing: 1) { ForEach(0..<numberOfColums, id: \.self) { idx in Text("Col \(idx)") .frame(width: 100) .padding() .background(Color.gray) } Spacer() } } } struct Item: Hashable { let id: String = UUID().uuidString var column: Int var row: Int }
求助诉求
希望确认该问题是否为SwiftUI ScrollView的已知Bug,寻求可落地的有效解决方案,若能实现滚动时单轴锁定的效果也可满足需求,当前实现无法投入生产使用,恳请提供可行思路。
内容的提问来源于stack exchange,提问作者phranck
相关产品推荐
相关产品推荐

