SwiftUI如何在List上方添加可滑出屏幕边缘的水平轮播
SwiftUI 复刻Watch应用顶部水平轮播边缘截断问题修复
问题描述
尝试复刻苹果原生Watch应用布局:页面顶部为水平滚动轮播区域,下方搭配List列表组件。当前代码运行后,第一个Section内的水平轮播滚动到屏幕边缘时会被截断,无法实现轮播内容滑出屏幕边缘的预期效果。
问题复现代码
let data: [String] = (0..<25).map { "Item \($0)" } let data2: [String] = (0..<3).map { "Item \($0)" } NavigationView { List { Section { ScrollView(.horizontal) { HStack { ForEach(data) { element in VStack { Text(element) } .padding() .background(Color(.secondarySystemBackground)) .cornerRadius(10) } } } } .listRowBackground(Color.clear) .listRowInsets(.init()) Section("Section 1") { ForEach(data2) { element in NavigationLink { Text("Destination") } label: { Label(element, systemImage: "calendar.circle.fill") } } } } .searchable(text: .constant(""), placement: .navigationBarDrawer(displayMode: .always)) .navigationTitle("Watch") }
目标参考效果

问题原因
截断问题来自两个系统默认行为:
- 默认InsetGrouped样式的List行自动开启子视图裁剪,超出行边界的内容会被直接裁切
- 水平ScrollView未做边距适配,初始内容位置和原生布局不对齐,且滚动视图自身默认裁剪超出边界的内容
修复后完整代码
let data: [String] = (0..<25).map { "Item \($0)" } let data2: [String] = (0..<3).map { "Item \($0)" } NavigationView { List { Section { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 12) { ForEach(data, id: \.self) { element in VStack { Text(element) } .padding() .background(Color(.secondarySystemBackground)) .cornerRadius(10) } } .padding(.horizontal, 16) } .scrollClipDisabled() // iOS17及以上使用,低版本可替换为.clipped(false) .frame(height: 100) // 根据卡片实际高度调整 } .listRowBackground(Color.clear) .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) .clipped(false) Section("Section 1") { ForEach(data2, id: \.self) { element in NavigationLink { Text("Destination") } label: { Label(element, systemImage: "calendar.circle.fill") } } } } .listStyle(.insetGrouped) .searchable(text: .constant(""), placement: .navigationBarDrawer(displayMode: .always)) .navigationTitle("Watch") }
关键调整说明
- 给轮播所在行添加
.clipped(false),关闭List行默认的边界裁剪,允许轮播内容滚动时滑出屏幕边缘 - 给ScrollView添加
.scrollClipDisabled(),关闭滚动视图自身的内容裁剪,避免滚动过程中边缘裁切 - 给轮播内容容器HStack添加16pt水平内边距,让第一个卡片和下方列表内容左对齐,匹配原生布局
- 给ScrollView设置固定高度,避免行高自适应异常
- 隐藏水平滚动条,匹配原生应用交互效果
- 给ForEach添加
id: \.self,修正原代码中字符串元素未遵循Identifiable协议的编译问题
内容的提问来源于stack exchange,提问作者TruMan1
相关产品推荐
相关产品推荐

