SwiftUI中点击按钮弹出确认对话框时页面自动上滚的问题求助
SwiftUI中点击按钮弹出确认对话框时页面自动上滚的问题求助
各位好,我最近在开发一个SwiftUI旅行行程应用,做了一个带双向滚动联动的页面,但遇到了一个头疼的小问题,想请教下大家。
先简单说下页面结构:
- 顶部是一个水平滚动的日期选择栏,点击某个日期可以让下方的垂直列表自动滚动到对应日期的行程
- 下方是垂直滚动的每日行程列表,滚动时会同步更新顶部激活的日期,用
scrollPosition和ScrollViewReader实现了这个双向联动逻辑
具体代码如下:
TripView 主视图代码
struct TripView: View { @Environment(\.dismiss) private var dismiss @Binding var trip: Trip @State private var activeDate: String? var body: some View { VStack(spacing: 0) { // 顶部水平日期选择栏 ScrollViewReader { proxy in ScrollView(.horizontal, showsIndicators: false) { LazyHStack(spacing: 16) { ForEach(trip.days, id: \.id) { day in Button(action: { withAnimation(.spring(duration: 0.3)) { activeDate = day.date } }, label: { VStack(spacing: 2) { Text(day.date.formatDate(fromFormat: "yyyy-MM-dd", toFormat: "d") ?? "") .background(activeDate == day.date ? Color.blue : Color.clear) } }) .id(day.date) } } } .onChange(of: activeDate) { oldValue, newValue in print("Active date changed to: \(newValue)") if let newValue { withAnimation { proxy.scrollTo(newValue, anchor: .center) } } } } // 下方垂直行程列表 ScrollView { LazyVStack(spacing: 0) { ForEach($trip.days) { $day in TripDayView( tripId: trip.id, day: $day ) .id(day.date) } } .scrollTargetLayout() } .scrollPosition(id: $activeDate, anchor: .top) } } }
TripDayView 每日行程子视图代码
struct TripDayView: View { @EnvironmentObject var tripManager: TripManager let tripId: Int @Binding var day: Day @State private var showingActionSheet: Bool = false var body: some View { Section { headerView ListStopsView(tripId: tripId, stops: $day.stops) } } var headerView: some View { VStack(alignment: .leading, spacing: 0) { HStack(spacing: 0) { VStack(alignment: .leading, spacing: 0) { Text(day.date.formatDate(fromFormat: "yyyy-MM-dd", toFormat: "EE, MMM d") ?? "") } Spacer() Button(action: { showingActionSheet = true }, label: { Image("Ellipsis Vertical") }) .confirmationDialog("", isPresented: $showingActionSheet, titleVisibility: .hidden) { Button("选项1") { // 后续逻辑 } Button("选项2") { // 后续逻辑 } Button("选项3") { // 后续逻辑 } } } } } }
遇到的问题
当我点击TripDayView里的那个三点按钮(触发showingActionSheet = true弹出确认对话框)时,下方的垂直行程列表会自动向上滚动一段距离。
我排查了一下,发现只要注释掉垂直列表的.scrollPosition(id: $activeDate, anchor: .top)这行代码,这个自动滚动的问题就消失了,但这行是实现滚动同步的关键,不能去掉。
想请教大家:
- 这个自动滚动的触发原因是什么?
- 有没有办法在保留双向滚动联动功能的前提下,解决这个弹出对话框时列表自动上滚的问题?
麻烦大家帮忙看看,谢谢啦!




