SwiftUI中ScrollViewReader的scrollTo方法无法正常工作问题排查
问题排查与解决方案
你的代码里scrollTo不生效的核心原因是没有给滚动目标视图添加对应的id标记,以下是具体分析和修复步骤:
1. 缺失视图ID标记
ScrollViewReader的scrollTo(_:)方法需要找到带有对应ID的具体视图,你在ForEach里指定的id: \.id只是用来标识列表项的唯一性,并不会自动给ExerciseTable视图附加可被定位的ID。
修复方法:给每个ExerciseTable添加.id(player.id)修饰符,让ScrollViewReader能精准定位到目标视图:
ForEach(players, id: \.id) { player in ExerciseTable(player: player) .frame(width: size.width) .id(player.id) // 新增这一行 }
2. 额外排查点
如果添加ID后仍不生效,可以检查以下两点:
- players数组是否实时更新:你在函数开头用
let players: [DSPlayer] = trainingController.currentExercise?.players ?? []定义数组,若trainingController.currentExercise变化时,这个函数没有重新执行,会导致ScrollView内的列表未同步更新。确保getTrainingTargetsScrollView方法是在View的body中调用的,或者依赖trainingController.currentExercise的变化触发重绘。 - scrollTo的锚点设置:默认
scrollTo会将目标视图居中,若需要滚动到视图的起始位置,可以指定anchor参数:value.scrollTo(id, anchor: .leading)
完整修复后的代码示例
func getTrainingTargetsScrollView(size: CGSize) -> some View { let players: [DSPlayer] = trainingController.currentExercise?.players ?? [] return ScrollViewReader { value in ScrollView(.horizontal) { HStack(spacing: 0) { ForEach(players, id: \.id) { player in ExerciseTable(player: player) .frame(width: size.width) .id(player.id) // 新增ID标记 } } } .onReceive(trainingController.$currentPlayer, perform: { newValue in if let id = newValue?.id { withAnimation { value.scrollTo(id, anchor: .leading) // 可选:指定锚点 } } }) .frame(height: size.height - 130) } }
内容的提问来源于stack exchange,提问作者Joris416
相关产品推荐
相关产品推荐

