[英]Limit drag to rectangle bounds in SwiftUI
I want to be able to drag an arrow shape around on top of an image in swiftUI.我希望能够在 swiftUI 中的图像顶部拖动箭头形状。 I have tried to simplify it and limit it to a rectangle here in the beginning.
我一开始就试图简化它并将其限制为一个矩形。 I have taken some inspiration from this post: Limit drag to circular bounds in SwiftUI
我从这篇文章中获得了一些灵感: 在 SwiftUI 中将拖动限制为圆形边界
And this is my take on it ATM.这是我对 ATM 的看法。 I hope someone can point me in the right direction :)
我希望有人能指出我正确的方向:)
So imagine that the gray rectangle is the image and the blue one is the arrow, then I only want to be able to drag the blue rectangle inside the gray rectangle.所以想象灰色矩形是图像,蓝色是箭头,那么我只想能够将蓝色矩形拖到灰色矩形内。
struct ImageView: View {
@State private var position = CGPoint(x: 100, y: 100)
private var rectSize: CGFloat = 600
var body: some View {
VStack {
Text("Current postion = (x: \(Int(position.x)), y: \(Int(position.y))")
Rectangle()
.fill(.gray)
.frame(width: rectSize, height: rectSize)
.overlay(
Rectangle()
.fill(.blue)
.frame(width: rectSize / 4, height: rectSize / 4)
.position(x: position.x, y: position.y)
.gesture(
DragGesture()
.onChanged({ value in
let currentLocation = value.location
let center = CGPoint(x: self.rectSize/2, y: self.rectSize/2)
let distance = center.distance(to: currentLocation)
if distance > self.rectSize / 2 {
let const = (self.rectSize / 2) / distance
let newLocX = (currentLocation.x - center.x) * const+center.x
let newLocY = (currentLocation.y - center.y) * const+center.y
self.position = CGPoint(x: newLocX, y: newLocY)
} else {
self.position = value.location
}
})
)
)
}
}
}
You're almost there.您快到了。 As you're outer shape is a rect, you don't need to calculate complicated distances.
由于你的外形是一个矩形,你不需要计算复杂的距离。 It's enough to check whether the position is still in the outer rect, and limit drag to its size values (0...rectSize).
检查位置是否仍在外部矩形中,并将拖动限制在其大小值(0...rectSize)就足够了。 If you don't want your selection frame to move over the borders, you have to correct by 1/2 of its size (rectSize / 4 / 2)
如果你不希望你的选择框移动到边界上,你必须修正它的 1/2 大小(rectSize / 4 / 2)
struct ContentView: View {
@State private var position = CGPoint(x: 100, y: 100)
private var rectSize: CGFloat = 350
var body: some View {
VStack {
Text("Current postion = (x: \(Int(position.x)), y: \(Int(position.y))")
Rectangle()
.fill(.gray)
.frame(width: rectSize, height: rectSize)
.overlay(
Rectangle()
.fill(.clear)
.border(.blue, width: 2.0)
.contentShape(Rectangle())
.frame(width: rectSize / 4, height: rectSize / 4)
.position(position)
.gesture(
DragGesture()
.onChanged { value in
// limit movement to min and max value
let limitedX = max(min(value.location.x, rectSize - rectSize / 8), rectSize / 8)
let limitedY = max(min(value.location.y, rectSize - rectSize / 8), rectSize / 8)
self.position = CGPoint(x: limitedX,
y: limitedY)
}
)
)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.