如何在watchOS应用中实现滑动切换日期功能?
问题:SwiftUI列表如何用滑动手势替换日期切换按钮?
我有如下SwiftUI视图:
struct ContentView: View { @State private var list: [listEntry] = [] var body: some View { NavigationStack { VStack { List { ForEach(list, id: \.title) { time in HStack { if !time.isTime { Spacer() Text(time.title) Spacer() } else { Text(time.title) Spacer() Text(dateFormatter.string(from: time.time!)) } } } Button(action: { userChosenDate = userChosenDate.addingTimeInterval(-86400) syncCalendarDates() list = updateList() }) { Image(systemName: "chevron.left.circle.fill") } Button(action: { userChosenDate = userChosenDate.addingTimeInterval(86400) syncCalendarDates() list = updateList() }) { HStack { Spacer() Image(systemName: "chevron.right.circle.fill") } } } .padding() }.navigationTitle("Simple app") } .onAppear { getCalendarWithLocation { complexCalendar in // Once the complex calendar is obtained, // update the list using the data obtained calendar = complexCalendar list = updateList() } } } }
目前我通过列表末尾的两个按钮切换日期并更新列表,但希望将按钮替换为滑动手势,请问这是否可行?
解决方案
当然可行,你可以通过SwiftUI的DragGesture实现左右滑动切换日期,具体修改步骤如下:
- 移除列表内的切换按钮:删掉List里的两个Button条目
- 添加滑动手势识别:给List(或整个内容容器)添加
gesture修饰符,通过DragGesture捕捉滑动动作 - 处理滑动逻辑:在手势结束时判断滑动方向,执行对应的日期更新和列表刷新操作
修改后的完整代码示例:
struct ContentView: View { @State private var list: [listEntry] = [] @State private var userChosenDate = Date() private let dateFormatter = DateFormatter() var body: some View { NavigationStack { VStack { List { ForEach(list, id: \.title) { time in HStack { if !time.isTime { Spacer() Text(time.title) Spacer() } else { Text(time.title) Spacer() Text(dateFormatter.string(from: time.time!)) } } } // 移除原有的两个切换按钮 } .padding() // 添加滑动手势 .gesture( DragGesture(minimumDistance: 30, coordinateSpace: .local) .onEnded { value in // 根据滑动方向判断操作 if value.translation.width > 50 { // 向右滑,切换到前一天 userChosenDate = userChosenDate.addingTimeInterval(-86400) } else if value.translation.width < -50 { // 向左滑,切换到后一天 userChosenDate = userChosenDate.addingTimeInterval(86400) } // 更新日历和列表 syncCalendarDates() // 加动画让列表刷新更流畅 withAnimation { list = updateList() } } ) } .navigationTitle("Simple app") } .onAppear { // 初始化日期格式化器示例 dateFormatter.dateStyle = .medium dateFormatter.timeStyle = .short getCalendarWithLocation { complexCalendar in calendar = complexCalendar list = updateList() } } } // 假设你已实现以下方法 func syncCalendarDates() {} func updateList() -> [listEntry] { [] } func getCalendarWithLocation(completion: (Any) -> Void) {} } // 建议让listEntry遵循Identifiable协议更规范 struct listEntry: Identifiable { let id = UUID() let title: String let isTime: Bool let time: Date? }
关键说明:
minimumDistance: 30:设置最小滑动距离,避免误触value.translation.width:通过横向位移判断方向,正数为右滑,负数为左滑withAnimation:给列表更新添加过渡动画,提升用户体验- 可根据需求调整滑动阈值(比如把50改成更适合的数值)
内容的提问来源于stack exchange,提问作者Ely Jacobi
相关产品推荐
相关产品推荐

