iOS15下SwiftUI ScrollView中ForEach相邻视图额外间距如何消除
问题原因
iOS 15 对 SwiftUI 容器的默认布局规则做了调整,当容器内直接放置多个子视图且未显式声明spacing参数时,系统会自动添加默认的自适应间距,这就是你升级后出现额外空隙的核心原因。你的示例代码中ScrollViewReader内部直接放置ForEach,系统会隐式创建一个带默认非零间距的VStack容器承载子视图,iOS 14 及更早版本的这类隐式容器默认间距为0,因此升级后出现样式异常。
解决方案
方案1:局部显式指定容器间距(推荐,对现有代码侵入最小)
直接在ForEach外层包裹显式声明spacing: 0的VStack即可消除额外间距,修改后的核心代码如下:
struct ContentView: View { let array: [IntItem] var body: some View { ScrollView { ScrollViewReader { thing in // 显式添加VStack并指定间距为0 VStack(spacing: 0) { ForEach(array) { item in ItemView(item: item) } } } } } }
如果你的布局是横向滚动的场景,换成HStack(spacing: 0)即可。如果ForEach是放在List容器中,除了上述操作外,还需要添加.listRowSpacing(0)修饰符消除系统自带的行间距。
方案2:全局修改默认容器间距(适合全项目统一调整)
如果项目中大量存在同类隐式容器布局,不想逐个修改,可以通过扩展View实现全局覆盖默认间距:
extension VStack where Content: View { init(alignment: HorizontalAlignment = .center, @ViewBuilder content: () -> Content) { self.init(alignment: alignment, spacing: 0, content: content) } } // 横向布局同理添加HStack的扩展 extension HStack where Content: View { init(alignment: VerticalAlignment = .center, @ViewBuilder content: () -> Content) { self.init(alignment: alignment, spacing: 0, content: content) } }
注意:该方案会把所有未显式声明spacing的VStack/HStack的默认间距改为0,调整前请确认符合你的项目设计规范
内容的提问来源于stack exchange,提问作者John Sorensen
相关产品推荐
相关产品推荐

