像在SwiftUI中没有navigationView的情况下那样向后滑动手势

像在SwiftUI中没有navigationView的情况下那样向后滑动手势,swift,swiftui,swift5,Swift,Swiftui,Swift5,我试图在SwiftUI中创建一个简单的游戏,我试图得到一个类似于navigationView的回击手势,但没有将我的视图放在navigationView中。由于这是一个游戏,添加NavigationView看起来不合适 这就是我到目前为止所做的: struct SwipingView : View { @State private var dragAmount = CGSize.zero @GestureState private var position = CGSize.zero

我试图在SwiftUI中创建一个简单的游戏,我试图得到一个类似于navigationView的回击手势,但没有将我的视图放在navigationView中。由于这是一个游戏,添加NavigationView看起来不合适

这就是我到目前为止所做的:

struct SwipingView : View {
  @State private var dragAmount = CGSize.zero
  @GestureState private var position = CGSize.zero
  func addToPosition(translation:CGSize) -> CGSize {
    return CGSize(width: dragAmount.width + translation.width, height: dragAmount.height + translation.height)
  }

  var body: some View{
    return ZStack(){
      Rectangle().fill(Color.red).frame(width: 100, height:400).scaleEffect(x:5,y:1,anchor: .leading)
        .offset(x: 190)
        .offset(x: addToPosition(translation: position).width )
        .gesture(
          DragGesture(minimumDistance: 20)
            .updating(self.$position){ value, state, translation in
              state = value.translation
            }
            .onEnded{ value in
              if value.translation.width > 50 {
                guard position.width + self.addToPosition(translation: CGSize(width:330, height:0)).width < 330-1 else {
                  return print("too far right")
                }
                self.dragAmount = self.addToPosition(translation: CGSize(width:330, height:0))
              } else {
                guard position.width + self.addToPosition(translation: CGSize(width:-330, height:0)).width > -330-1 else {
                  return print("too far left")
                }
                self.dragAmount = self.addToPosition(translation: CGSize(width:-330, height:0))
              }
            }
        )
    }.animation(Animation.linear)
  }
}
struct SwipingView:视图{
@国家私有变量dragAmount=CGSize.zero
@GestureState私有变量位置=CGSize.zero
func addToPosition(翻译:CGSize)->CGSize{
返回CGSize(宽度:dragAmount.width+translation.width,高度:dragAmount.height+translation.height)
}
var body:一些观点{
返回ZStack(){
矩形()
.偏移量(x:190)
.偏移量(x:addToPosition(平移:位置).宽度)
.手势(
牵引力(最小距离:20)
.更新(self.$position){中的值、状态、翻译
state=value.translation
}
.onEnded{中的值
如果value.translation.width>50{
防护位置.宽度+自身.添加位置(平移:CGSize(宽度:330,高度:0))。宽度<330-1{
返回打印(“太右”)
}
self.dragAmount=self.addToPosition(翻译:CGSize(宽度:330,高度:0))
}否则{
防护位置.宽度+自身.添加位置(翻译:CGSize(宽度:-330,高度:0))。宽度>-330-1其他{
返回打印(“太左”)
}
self.dragAmount=self.addToPosition(翻译:CGSize(宽度:-330,高度:0))
}
}
)
}.动画(动画.线性)
}
}
我对swift还是个新手,所以我很可能遗漏了一些明显的东西,尽管我已经查看了堆栈溢出,但找不到我想要的东西

这就是它看起来的样子。如您所见,我可以从视图上的任何位置滑动视图,但我只希望在左侧边缘滑动,甚至只滑动左侧的前5%


这里有一个可能的解决方案-想法是将手势附加到左侧所需宽度的覆盖上。使用Xcode 12/iOS 14进行测试

注意:在演示中,活动区域为
Color.blue
而不是
Color.clear
以获得更好的可视性

struct SwipingView:视图{
@国家私有变量dragAmount=CGSize.zero
@GestureState私有变量位置=CGSize.zero
func addToPosition(翻译:CGSize)->CGSize{
返回CGSize(宽度:dragAmount.width+translation.width,高度:dragAmount.height+translation.height)
}
var body:一些观点{
返回ZStack(){
矩形()
.overlay(颜色.清晰.边框(宽度:40)//50{
防护位置.宽度+自身.添加位置(平移:CGSize(宽度:330,高度:0))。宽度<330-1{
返回打印(“太右”)
}
self.dragAmount=self.addToPosition(翻译:CGSize(宽度:330,高度:0))
}否则{
防护位置.宽度+自身.添加位置(翻译:CGSize(宽度:-330,高度:0))。宽度>-330-1其他{
返回打印(“太左”)
}
self.dragAmount=self.addToPosition(翻译:CGSize(宽度:-330,高度:0))
}
}
),对齐:。前导)
.偏移量(x:190)
.偏移量(x:addToPosition(平移:位置).宽度)
}.动画(动画.线性)
}
}
struct SwipingView : View {
  @State private var dragAmount = CGSize.zero
  @GestureState private var position = CGSize.zero
  func addToPosition(translation:CGSize) -> CGSize {
    return CGSize(width: dragAmount.width + translation.width, height: dragAmount.height + translation.height)
  }

  var body: some View{
    return ZStack(){
      Rectangle().fill(Color.red).frame(width: 100, height:400).scaleEffect(x:5,y:1,anchor: .leading)
        .overlay(Color.clear.frame(width: 40)       // << make width as needed
        .contentShape(Rectangle())
        .gesture(
          DragGesture(minimumDistance: 20)
            .updating(self.$position){ value, state, translation in
              state = value.translation
            }
            .onEnded{ value in
              if value.translation.width > 50 {
                guard position.width + self.addToPosition(translation: CGSize(width:330, height:0)).width < 330-1 else {
                  return print("too far right")
                }
                self.dragAmount = self.addToPosition(translation: CGSize(width:330, height:0))
              } else {
                guard position.width + self.addToPosition(translation: CGSize(width:-330, height:0)).width > -330-1 else {
                  return print("too far left")
                }
                self.dragAmount = self.addToPosition(translation: CGSize(width:-330, height:0))
              }
            }
        ), alignment: .leading)
        .offset(x: 190)
        .offset(x: addToPosition(translation: position).width )
    }.animation(Animation.linear)
  }
}