SwiftUI 无法 PanGesture 图像
SwiftUI Can't PanGesture an Image
我无法在 SwiftUI 中找到与平移手势等效的手势。我确实看到
并使用放大、点击、拖动和旋转 - 但我没有看到任何内置平移。在里面
下面的代码片段我添加了一个图像并允许用户缩放 - 但我想要
用户还可以移动缩放图像以聚焦感兴趣的区域。拖动,的
当然不做这个工作 - 它只是移动框架。
我尝试在顶部叠加框架并移动底部图像,但无法做到这一点
要么工作。
struct ContentView: View {
@State var scale: CGFloat = 1.0
@State var isScaled: Bool = false
@State private var dragOffset = CGSize.zero
var body: some View {
GeometryReader { geo in
VStack {
ZStack{
RoundedRectangle(cornerRadius: 40)
.foregroundColor(Color.white)
.frame(width: geo.size.width - 45, height: geo.size.width - 45)
.shadow(radius: 10)
Image("HuckALaHuckMedium")
.resizable()
.scaleEffect(self.scale)
.frame(width: geo.size.width - 60, height: geo.size.width - 60)
.cornerRadius(40)
.aspectRatio(contentMode: .fill)
.shadow(radius: 10, x: 20, y: 20)
//need pan not drag
.gesture(
DragGesture()
.onChanged { self.dragOffset = [=10=].translation }
.onEnded { _ in self.dragOffset = .zero }
)
//this works but you can't "zoom twice"
.gesture(MagnificationGesture()
.onChanged { value in
self.scale = self.isScaled ? 1.0 : value.magnitude
}
.onEnded({ value in
//self.scale = 1.0
self.isScaled.toggle()
})
)
.animation(.easeInOut)
.offset(self.dragOffset)
}//zstack
Spacer()
}
}
}
}
原始图像示例:
缩放后的图像 - 但拖动而不是平移:
如有任何指导,我们将不胜感激。 Xcode11.3 (11C29)
对于其他人。这真的很简单。确保在允许拖动之前完成放大 - 它会像平底锅一样工作。首先定义拖动手势:
let dragGesture = DragGesture()
.onChanged { (value) in
self.translation = value.translation
}
.onEnded { (value) in
self.viewState.width += value.translation.width
self.viewState.height += value.translation.height
self.translation = .zero
}
然后创建一个 @State 值,在激活放大手势后将其切换为 true。当您将手势附加到图像时,有条件地这样做:
.gesture(self.canBeDragged ? dragGesture : nil)
我来晚了一点,但对于任何正在寻找的人,请尝试一下,因为它对我有用。您要做的是在缩小 MagnificationGesture.onChanged() 生命周期后立即更改图像的偏移量。
var magnification: some Gesture {
MagnificationGesture()
.updating($magnifyBy) {
.....
}
.onChanged() { _ in
//Zoom Out value of magnifyBy < 1.0
if self.magnifyBy <= 0.6{
//Change offset of image after zoom out to center of screen
self.currentPosition = CGSize(width: 1.0, height: 1.0)
}
self.newPosition = self.currentPosition
}
.onEnded{
.....
} }
var body: some View{
Image()
.offset(x: self.currentPosition.width, y: self.currentPosition.height)}
有任何问题请告诉我
为了让它更简单、更易读,我为此创建了一个 extension/modifier
struct DraggableView: ViewModifier {
@State var offset = CGPoint(x: 0, y: 0)
func body(content: Content) -> some View {
content
.gesture(DragGesture(minimumDistance: 0)
.onChanged { value in
self.offset.x += value.location.x - value.startLocation.x
self.offset.y += value.location.y - value.startLocation.y
})
.offset(x: offset.x, y: offset.y)
}
}
extension View {
func draggable() -> some View {
return modifier(DraggableView())
}
}
现在您所要做的就是调用修饰符:
Image(systemName: "plus")
.draggable()
我无法在 SwiftUI 中找到与平移手势等效的手势。我确实看到 并使用放大、点击、拖动和旋转 - 但我没有看到任何内置平移。在里面 下面的代码片段我添加了一个图像并允许用户缩放 - 但我想要 用户还可以移动缩放图像以聚焦感兴趣的区域。拖动,的 当然不做这个工作 - 它只是移动框架。
我尝试在顶部叠加框架并移动底部图像,但无法做到这一点 要么工作。
struct ContentView: View {
@State var scale: CGFloat = 1.0
@State var isScaled: Bool = false
@State private var dragOffset = CGSize.zero
var body: some View {
GeometryReader { geo in
VStack {
ZStack{
RoundedRectangle(cornerRadius: 40)
.foregroundColor(Color.white)
.frame(width: geo.size.width - 45, height: geo.size.width - 45)
.shadow(radius: 10)
Image("HuckALaHuckMedium")
.resizable()
.scaleEffect(self.scale)
.frame(width: geo.size.width - 60, height: geo.size.width - 60)
.cornerRadius(40)
.aspectRatio(contentMode: .fill)
.shadow(radius: 10, x: 20, y: 20)
//need pan not drag
.gesture(
DragGesture()
.onChanged { self.dragOffset = [=10=].translation }
.onEnded { _ in self.dragOffset = .zero }
)
//this works but you can't "zoom twice"
.gesture(MagnificationGesture()
.onChanged { value in
self.scale = self.isScaled ? 1.0 : value.magnitude
}
.onEnded({ value in
//self.scale = 1.0
self.isScaled.toggle()
})
)
.animation(.easeInOut)
.offset(self.dragOffset)
}//zstack
Spacer()
}
}
}
}
原始图像示例:
缩放后的图像 - 但拖动而不是平移:
如有任何指导,我们将不胜感激。 Xcode11.3 (11C29)
对于其他人。这真的很简单。确保在允许拖动之前完成放大 - 它会像平底锅一样工作。首先定义拖动手势:
let dragGesture = DragGesture()
.onChanged { (value) in
self.translation = value.translation
}
.onEnded { (value) in
self.viewState.width += value.translation.width
self.viewState.height += value.translation.height
self.translation = .zero
}
然后创建一个 @State 值,在激活放大手势后将其切换为 true。当您将手势附加到图像时,有条件地这样做:
.gesture(self.canBeDragged ? dragGesture : nil)
我来晚了一点,但对于任何正在寻找的人,请尝试一下,因为它对我有用。您要做的是在缩小 MagnificationGesture.onChanged() 生命周期后立即更改图像的偏移量。
var magnification: some Gesture {
MagnificationGesture()
.updating($magnifyBy) {
.....
}
.onChanged() { _ in
//Zoom Out value of magnifyBy < 1.0
if self.magnifyBy <= 0.6{
//Change offset of image after zoom out to center of screen
self.currentPosition = CGSize(width: 1.0, height: 1.0)
}
self.newPosition = self.currentPosition
}
.onEnded{
.....
} }
var body: some View{
Image()
.offset(x: self.currentPosition.width, y: self.currentPosition.height)}
有任何问题请告诉我
为了让它更简单、更易读,我为此创建了一个 extension/modifier
struct DraggableView: ViewModifier {
@State var offset = CGPoint(x: 0, y: 0)
func body(content: Content) -> some View {
content
.gesture(DragGesture(minimumDistance: 0)
.onChanged { value in
self.offset.x += value.location.x - value.startLocation.x
self.offset.y += value.location.y - value.startLocation.y
})
.offset(x: offset.x, y: offset.y)
}
}
extension View {
func draggable() -> some View {
return modifier(DraggableView())
}
}
现在您所要做的就是调用修饰符:
Image(systemName: "plus")
.draggable()