Reputation: 118
Hello I have a Drag Gesture function. You can see what this function is for by looking at the code.
My problem is this: I just want the view to move down to a certain extent. How can I do that?
func onChanged(value: DragGesture.Value){
if value.startLocation.y < value.location.y {
playerModel.offset = value.translation
let screenHeight = UIScreen.main.bounds.width - 50
let progress = playerModel.offset.height / screenHeight
if 1 - progress > 0.925 {
playerModel.scale = 1 - progress
}
}
}
Upvotes: 0
Views: 1131
Reputation: 564
Try this:
struct ContentView: View {
@State private var currentPosition: CGSize = .zero
@State private var newPosition: CGSize = .zero
@State private var screenBounds: CGRect = .zero
@State private var boundsPosition: CGSize = .zero
@State private var verticalLimit: CGSize = .zero
@State private var orientation = UIDevice.current.orientation
let heightLimit: CGFloat = 100
let orientationChanged = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)
.makeConnectable()
.autoconnect()
var body: some View {
Rectangle()
.frame(width: 100, height: 100)
.foregroundColor(.green)
.offset(x: currentPosition.width, y: currentPosition.height)
.onAppear() {
currentPosition = .zero
newPosition = .zero
setTravelLimits()
limitTravel()
}
.onReceive(orientationChanged) {_ in
setTravelLimits()
limitTravel()
}
.gesture(
DragGesture()
.onChanged { value in
verticalLimit.height = currentPosition.height
currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
limitTravel()
}
.onEnded { value in
currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
limitTravel()
newPosition = currentPosition
})
}
func setTravelLimits() {
screenBounds = UIScreen.main.bounds
boundsPosition.width = 0
boundsPosition.height = (screenBounds.height / 2 ) - heightLimit
}
func limitTravel() {
currentPosition.height = currentPosition.height < boundsPosition.height ? currentPosition.height: boundsPosition.height
currentPosition.height = currentPosition.height > verticalLimit.height ? currentPosition.height: verticalLimit.height
currentPosition.width = currentPosition.width > boundsPosition.width ? boundsPosition.width: currentPosition.width
currentPosition.width = currentPosition.width < -boundsPosition.width ? -boundsPosition.width: currentPosition.width
}
}
Upvotes: 0
Reputation: 564
Here's an example of how to limit movement of a draggable rectangle that recognizes device rotation and doesn't use GeometryReader.
import SwiftUI
struct ContentView: View {
@State private var currentPosition: CGSize = .zero
@State private var newPosition: CGSize = .zero
@State private var screenBounds: CGRect = .zero
@State private var boundsPosition: CGSize = .zero
@State private var orientation = UIDevice.current.orientation
let widthLimit: CGFloat = 100
let heightLimit: CGFloat = 100
let orientationChanged = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)
.makeConnectable()
.autoconnect()
var body: some View {
Rectangle()
.frame(width: 100, height: 100)
.foregroundColor(.green)
.offset(x: currentPosition.width, y: currentPosition.height)
.onAppear() {
currentPosition = .zero
newPosition = .zero
setTravelLimits()
limitTravel()
}
.onReceive(orientationChanged) {_ in
setTravelLimits()
limitTravel()
}
.gesture(
DragGesture()
.onChanged { value in
currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
limitTravel()
}
.onEnded { value in
currentPosition = CGSize(width: value.translation.width + newPosition.width, height: value.translation.height + newPosition.height)
limitTravel()
newPosition = currentPosition
})
}
func setTravelLimits() {
screenBounds = UIScreen.main.bounds
boundsPosition.width = (screenBounds.width / 2) - widthLimit
boundsPosition.height = (screenBounds.height / 2) - heightLimit
}
func limitTravel() {
currentPosition.height = currentPosition.height > boundsPosition.height ? boundsPosition.height: currentPosition.height
currentPosition.height = currentPosition.height < -boundsPosition.height ? -boundsPosition.height: currentPosition.height
currentPosition.width = currentPosition.width > boundsPosition.width ? boundsPosition.width: currentPosition.width
currentPosition.width = currentPosition.width < -boundsPosition.width ? -boundsPosition.width: currentPosition.width
}
}
Upvotes: 1