我正在尝试在 SwiftUI 中实现视频修剪器 UI,如下所示:
struct SimpleTrimmer: View {
@State private var startPosition: CGFloat = 0
@GestureState private var isDragging: Bool = false
@State private var lastStartPosition: CGFloat = .zero
@State private var frameWidth:CGFloat = 300
var body: some View {
HStack(spacing: 10) {
Image(systemName: "chevron.compact.left")
.frame(height:70)
.frame(width:20)
.padding(.horizontal, 5)
.background(Color.blue)
.offset(x: startPosition)
.gesture(
DragGesture(minimumDistance: 0)
.updating($isDragging, body: { value, out, transaction in
out = true
})
.onChanged { value in
let translation = value.translation.width
startPosition = translation + lastStartPosition
}.onEnded { _ in
lastStartPosition = startPosition
NSLog("Last start position \(lastStartPosition)")
}
)
Spacer()
Image(systemName: "chevron.compact.right")
.frame(height:70)
.frame(width:20)
.padding(.horizontal, 5)
.background(Color.blue)
}
.foregroundColor(.black)
.font(.title3.weight(.semibold))
.padding(.horizontal, 7)
.padding(.vertical, 3)
.background(.yellow)
.clipShape(RoundedRectangle(cornerRadius: 7))
.frame(width: frameWidth)
// .offset(x: startPosition)
.onGeometryChange(for: CGFloat.self) { proxy in
proxy.size.width
} action: { width in
print("width = \(width)")
}
}
}
这适用于拖动时移动修剪器的左手。我还需要SimpleTrimmer
拖动末端时缩小视图。无论我做什么(例如调整主 HStack 的偏移量和宽度等),它都不起作用。
为了使背景框能够与拖动手势协调变化,您需要在拖动时调整背景的宽度。目前,宽度是固定的,因此看不到任何变化。
我建议进行以下更改:
使用
GestureState
变量记录拖动偏移量。当拖动手势结束时,它会自动重置为 0,非常方便。使用拖动偏移来控制前导填充,而不是应用 x 偏移。
应对修剪器(V 形)以及填充背景应用相同的前导填充。
可以将填充的背景绘制为
RoundedRectangle
,而不必使用剪辑形状。这样可以更轻松地应用填充。以下是更新的版本:
编辑根据您的评论,我尝试在右侧的修剪器(V 形)中添加拖动手势,希望可以按照与上面的前导填充相同的方式调整尾随填充。
当我尝试时,修剪器的移动很不稳定。我认为这是因为间隔的大小和修剪器上的填充之间存在相互依赖关系。虽然它似乎适用于前导填充的情况,但它对尾随填充的效果不佳。
如果您在修剪器上设置 x 偏移量(就像您最初使用的那样),效果会更好。这也意味着要为状态变量找到更好的名称!
这是两个修剪器上均带有拖动手势的更新版本: