在SwiftUI中向后滑动手势就像没有导航一样

时间:2020-08-08 01:24:36

标签: swift swiftui swift5

我正在尝试在SwiftUI中创建一个简单的游戏,并且我试图获得与navigationView类似的向后滑动手势,但没有将我的视图放入NavigationView中。由于这是一个游戏,因此添加naviagationView会显得不合适。

这是我到目前为止所拥有的:

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

我还是个新手,所以即使我已经看过堆栈溢出并且找不到我想要的东西,我还是可能会缺少一些明显的信息。

这是它的外观。如您所见,我可以从视图的任何位置滑动视图,但是我想向左滑动,甚至只是向左滑动第一个5%。

enter image description here

1 个答案:

答案 0 :(得分:1)

这里是可能的解决方案-想法是将手势附加到需要的左侧宽度尽可能大的叠加层上。经过Xcode 12 / iOS 14的测试

注意:在演示中,活动区域设置为Color.blue而非Color.clear,以提高可见度

demo

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