如果您玩过Apple的Room Tutorial(链接:../WWDC2019/204/),则按照以下代码,我添加了一个小的触摸缩放手势(由于@Alladinian和brar07)。
但是,触摸和平移图像时,图像会移出屏幕,并且不会返回其原始位置。 只需少量修改,您就可以将此代码复制并粘贴到Apple的项目中。
要求: 1):图像应停留在图像框的范围内,即,缩放时,图像的边缘不应超出图像边缘。定义的框架(如果未定义框架,则为屏幕)。 2):图像应返回其原始位置。
最终结果类似于某些网站上产品图片的鼠标悬停方式。
import SwiftUI
struct RoomDetail: View {
let room : Room
@State var scale: CGFloat = 1.0
@State var isTouchingScreen = false
@State var isZoomedIn = false
@State var pointTouchedOnScreen: CGPoint = CGPoint.zero
@State var panSize: CGSize = CGSize.zero
@State var fingerState: String = "Finger is not touching the image"
var body: some View {
ZStack {
// Show the room selected by the user, implement zooming capabilities
GeometryReader { reader in
Image("\(self.room.name)" + "_Thumb")
.resizable()
.offset(x: self.panSize.width, y: self.panSize.height)
.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global)
.onChanged { (value) in
self.fingerState = "Finger is touching the image" // for debug purpose only
self.isZoomedIn = true
self.isTouchingScreen = true
self.pointTouchedOnScreen = value.startLocation
self.scale = 1.1
let offsetWidth = (reader.frame(in: .global).maxX * self.scale - reader.frame(in: .global).maxX) / 2
let newDraggedWidth = self.panSize.width * self.scale
if (newDraggedWidth > offsetWidth) {
self.panSize = CGSize(width: (value.translation.width + self.panSize.width), height: (value.translation.height + self.panSize.height))
} else if (newDraggedWidth < -offsetWidth) {
self.panSize = CGSize(width: (value.translation.width + self.panSize.width), height: (value.translation.height + self.panSize.height))
} else {
self.panSize = CGSize(width: (value.translation.width + self.panSize.width), height: (value.translation.height + self.panSize.height))
}
}
.onEnded { _ in
self.fingerState = "Finger is not touching the image" // for debug purpose only
self.isZoomedIn = false
self.isTouchingScreen = false
})
.aspectRatio(contentMode: self.isZoomedIn ? .fill : .fit)
.scaleEffect(self.isTouchingScreen ? self.scale : 1, anchor: UnitPoint(x: self.pointTouchedOnScreen.x / reader.frame(in: .global).maxX, y: self.pointTouchedOnScreen.y / reader.frame(in: .global).maxY))
.animation(.easeInOut(duration: 1))
.frame(maxWidth: UIScreen.main.bounds.size.width - 50, maxHeight: UIScreen.main.bounds.size.height - 200, alignment: .center)
.clipped()
.offset(x: 0, y: -50)
}
}
}
struct RoomDetail_Previews: PreviewProvider {
static var previews: some View {
RoomDetail(room: testData[0])
}
}
答案 0 :(得分:1)
我不知道这是否能准确回答您的问题,但我想做个注释:
这不起作用,图像将不会“裁剪”为图像框架的大小:
Image(uiImage: self.userData.image!)
.resizable()
.offset(x: self.currentPosition.width, y: self.currentPosition.height)
.aspectRatio(contentMode: .fill)
.frame(maxWidth:metrics.size.width * 0.60, maxHeight: metrics.size.height * 0.60, alignment: .top)
.scaleEffect(self.scale)
.clipped()
.foregroundColor(.gray)
此DID起作用:
Image(uiImage: self.userData.image!)
.resizable()
.scaleEffect(self.scale)
.offset(x: self.currentPosition.width, y: self.currentPosition.height)
.aspectRatio(contentMode: .fill)
.frame(maxWidth:metrics.size.width * 0.60, maxHeight: metrics.size.height * 0.60, alignment: .top)
.clipped()
.foregroundColor(.gray)
唯一的区别是在帧之前应用了scaleEffect。 (在这种情况下,我有拖动手势和缩放手势)。
花了很多时间试图解决这个问题,但不确定它是否能解决您的问题,但可能对某人有用。