你好,在我的应用程序中,我为用户提供了按下图像以全屏显示的选项.当图像以全屏显示时,用户可以放大它,并应该能够拖动它来查看图像的其他部分.目前,当图像被放大时,我试图将其拖动到任何一侧,它会重新居中,拖拽效果不佳.另外,我只能放大到中心.我如何修改这段代码,以便在放大时向任何一侧的拖动手势都是平滑的,并且可以在图像的两侧而不仅仅是中心进行zoom 手势.我很感谢你的帮助.KFImage是一个简单的包,可以从url渲染图像,您可以使用以下url:https://github.com/onevcat/Kingfisher.git将其快速添加到Xcode
import SwiftUI
import Kingfisher
import UIKit
struct ContentView: View {
@State private var myPhoto = "https://firebasestorage.googleapis.com:443/v0/b/hustle-85b6c.appspot.com/o/messages%2F7AC5914A-6239-41CF-85EF-E1C0F25C0A84?alt=media&token=8720789b-7cdd-410c-9532-143a2bcf3f3b"
@State private var currentScale: CGFloat = 1.0
@State private var previousScale: CGFloat = 1.0
@State private var currentOffset = CGSize.zero
@State private var previousOffset = CGSize.zero
@State var imageHeight: Double = 0.0
@State var imageWidth: Double = 0.0
var body: some View {
ZStack {
Rectangle().foregroundColor(.black)
GeometryReader { geometry in
KFImage(URL(string: myPhoto))
.resizable()
.aspectRatio(contentMode: .fit)
.scaleEffect(max(self.currentScale, 1.0))
.offset(x: self.currentOffset.width + (widthOrHeight(width: true) - imageWidth) / 2.0, y: self.currentOffset.height + (widthOrHeight(width: false) - imageHeight) / 2.0)
.background ( /// this background is to center the image (image loaded async so have to wait for it to load and then get height)
GeometryReader { proxy in
Color.clear
.onChange(of: proxy.size.height) { _ in
imageHeight = proxy.size.height
imageWidth = proxy.size.width
}
}
)
.gesture(
SimultaneousGesture(
DragGesture()
.onChanged { value in
let deltaX = value.translation.width - self.previousOffset.width
let deltaY = value.translation.height - self.previousOffset.height
previousOffset.width = value.translation.width
previousOffset.height = value.translation.height
let newOffsetWidth = self.currentOffset.width + deltaX / self.currentScale
let newOffsetHeight = self.currentOffset.height + deltaY / self.currentScale
withAnimation(.linear(duration: 0.25)){
if abs(newOffsetWidth) <= geometry.size.width - 200.0 && abs(newOffsetWidth) >= -200.0 {
self.currentOffset.width = newOffsetWidth
}
if abs(newOffsetHeight) < 450 {
self.currentOffset.height = newOffsetHeight
}
}
}
.onEnded { _ in
withAnimation(.easeInOut){
if currentScale < 1.2 {
self.previousOffset = CGSize.zero
self.currentOffset = CGSize.zero
}
}
},
MagnificationGesture().onChanged { value in
let delta = value / self.previousScale
let newScale = self.currentScale * delta
withAnimation {
if newScale <= 3.5 {
self.previousScale = value
self.currentScale = newScale
}
if newScale < 1.3 {
self.previousScale = 1.0
self.currentScale = 1.0
self.previousOffset = CGSize.zero
self.currentOffset = CGSize.zero
}
}
}
)
)
}
}.ignoresSafeArea()
}
}