简体   繁体   中英

SwiftUI - Moving the view in one direction with Drag Gesture

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
        }
    }
}

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
  }
}

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
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM