SwiftUI视频时间线拖拽问题:实现位移式拖动而非定位拖动
SwiftUI视频时间线拖拽交互修正方案
问题核心
你遇到的问题是直接将拖拽的绝对坐标赋值给矩形偏移,没有记录点击时光标与矩形的相对位置,导致矩形瞬间跳转到光标所在位置。
解决思路
要实现像PowerDirector那样的拖拽逻辑,需在拖拽开始时记录两个关键信息:
- 矩形当前的初始偏移量
- 光标相对于矩形左边缘的水平位置(即点击点在矩形内的x坐标)
拖拽过程中,通过当前光标位置 - 相对位置计算矩形新的偏移量,确保矩形跟随拖拽位移移动,而非直接跳转到光标位置。
完整代码示例
import SwiftUI struct VideoTimelineView: View { // 视频片段的水平偏移量 @State private var videoOffset: CGFloat = 0 // 存储拖拽起始信息:(矩形初始偏移, 光标相对矩形的X位置) @State private var dragStartData: (initialOffset: CGFloat, touchRelativeX: CGFloat)? var body: some View { VStack { // 时间线背景 Rectangle() .fill(Color.gray.opacity(0.2)) .frame(height: 60) .overlay( // 模拟视频片段的灰色矩形 Rectangle() .fill(Color.gray) .frame(width: 150, height: 50) .offset(x: videoOffset) .gesture( DragGesture() .onChanged { gesture in if dragStartData == nil { // 拖拽开始时记录初始状态 let relativeTouchX = gesture.location.x - videoOffset dragStartData = (videoOffset, relativeTouchX) } // 计算新偏移:当前光标位置 - 相对位置,保证矩形跟随拖拽位移移动 let newOffset = gesture.location.x - dragStartData!.touchRelativeX videoOffset = newOffset } .onEnded { _ in // 拖拽结束清空记录 dragStartData = nil } ) ) } .padding() } } struct VideoTimelineView_Previews: PreviewProvider { static var previews: some View { VideoTimelineView() } }
额外优化(可选)
如果需要限制视频片段不能拖出时间线边界,可以在设置videoOffset时添加边界判断:
// 获取时间线可用宽度(减去左右padding) let timelineWidth = UIScreen.main.bounds.width - 40 // 最大允许偏移:时间线宽度 - 视频片段宽度 let maxOffset = timelineWidth - 150 // 限制偏移在0到maxOffset之间 videoOffset = max(0, min(newOffset, maxOffset))
这样就能实现符合预期的拖拽交互,点击视频任意位置拖动时,视频会按照拖拽的位移量平稳移动。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

