IOS SwiftUI中ScrollView嵌套引起的滑动距离监听实效解决方案

发布时间:2026/10/30 23:06:48
IOS SwiftUI中ScrollView嵌套引起的滑动距离监听实效解决方案 文章目录一、前言二、核心代码一、前言在IOS中使用SwiftUI进行ScrollView滑动嵌套处理的时候想要监听某个滑动组件的滑动距离时候会出现外部滑动控件监听失效(或者距离不是真实的)的问题这里将解决方式记录如下。相关效果如下二、核心代码NestedScrollViews,swift//// NestedScrollViewOffsetTracker.swift// 解决SwiftUI中嵌套ScrollView无法监听滚动距离的问题//// 功能说明// 1. 可靠监听嵌套ScrollView的滚动距离// 2. 处理内外层ScrollView的手势冲突// 3. 提供清晰的滚动距离数值//importSwiftUI// 滚动偏移管理器classScrollOffsetManager:ObservableObject{PublishedvarouterOffset:CGFloat0PublishedvarinnerOffset:CGFloat0}// 外层滚动视图structOuterScrollView:View{ObservedObjectvarmanager:ScrollOffsetManagerStateprivatevaranchorFrame:CGRect.zerovarbody:someView{ScrollView{VStack(spacing:20){// 用于追踪的锚点视图Color.clear.frame(height:1).background(// GeometryReader { proxy in// Color.clear// .onAppear {// anchorFrame proxy.frame(in: .global)// }// .onChange(of: proxy.frame(in: .global)) { newFrame in// // 计算滚动偏移初始位置 - 当前位置// manager.outerOffset anchorFrame.minY - newFrame.minY// }// }GeometryReader{proxyin// 优化逻辑防止过早获取滚动位置Color.clear.onAppear{// 延迟设置锚点框架确保视图已经稳定DispatchQueue.main.asyncAfter(deadline:.now()0.1){anchorFrameproxy.frame(in:.global)// 确保初始偏移量为0manager.outerOffset0debugPrint(YM----初始锚点位置:\(anchorFrame.minY))}}.onChange(of:proxy.frame(in:.global)){newFramein// 只有当锚点框架已经设置后才更新偏移量if!anchorFrame.isEmpty{// 计算滚动偏移初始位置 - 当前位置manager.outerOffsetanchorFrame.minY-newFrame.minYdebugPrint(YM----列表滚动位置:\(manager.outerOffset))}}})Text(外层滚动距离:\(manager.outerOffset,specifier:%.2f)).font(.title).padding().background(Color.yellow).cornerRadius(8)// 内层滚动视图InnerScrollView(manager:manager).frame(height:400).background(Color.gray.opacity(0.1)).cornerRadius(12)ForEach(1..20){iinText(外层内容\(i)).frame(maxWidth:.infinity).padding().background(Color.green).foregroundColor(.white).cornerRadius(8)}}.padding()}.onAppear{// 重置滚动偏移manager.outerOffset0// 如果有groupId则滚动到对应位置// if let groupId groupId {// DispatchQueue.main.asyncAfter(deadline: .now() 0.2) {// withAnimation {// proxy.scrollTo(groupId, anchor: .center)// }//}//}}}}// 内层滚动视图structInnerScrollView:View{ObservedObjectvarmanager:ScrollOffsetManagerStateprivatevaranchorFrame:CGRect.zerovarbody:someView{ScrollView{VStack(spacing:15){// 用于追踪的锚点视图Color.clear.frame(height:1).background(GeometryReader{proxyinColor.clear.onAppear{anchorFrameproxy.frame(in:.global)}.onChange(of:proxy.frame(in:.global)){newFramein// 计算滚动偏移初始位置 - 当前位置manager.innerOffsetanchorFrame.minY-newFrame.minY}})Text(内层滚动距离:\(manager.innerOffset,specifier:%.2f)).font(.title).padding().background(Color.cyan).cornerRadius(8)ForEach(1..30){iinText(内层内容\(i)).frame(maxWidth:.infinity).padding().background(Color.blue).foregroundColor(.white).cornerRadius(8)}}.padding()}// 确保内层手势优先.highPriorityGesture(DragGesture())}}// 主视图structNestedScrollViews:View{StateObjectprivatevarscrollManagerScrollOffsetManager()varbody:someView{OuterScrollView(manager:scrollManager)}}structNestedScrollViews_Previews:PreviewProvider{staticvarpreviews:someView{NestedScrollViews()}}

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询