繁体   English   中英

SwiftUI - 使用拖动手势在一个方向上移动视图

[英]SwiftUI - Moving the view in one direction with Drag Gesture

您好,我有一个拖动手势 function。 您可以通过查看代码来了解这个 function 的用途。

我的问题是:我只想让视图向下移动到一定程度。 我怎样才能做到这一点?

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

下面是一个示例,说明如何限制识别设备旋转且不使用 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
  }
}

尝试这个:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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