SwiftUI:在DragGesture视图上开始滑动时,ScrollView中的DragGesture不注册滚动

时间:2020-03-27 08:18:30

标签: swift animation scrollview swiftui gesture

所以我有一个非常好的动画,当用户按下视图时,该动画会在手指下“弹跳”,就像它对触摸做出反应一样。

初始目标

我需要在用户按下视图时进行注册(在此示例中为黑色矩形),所以我可以开始缩小它,然后在他们在视图上释放时进行注册,因此我可以让它恢复到原始大小。用户仍需要能够在ScrollView

中正常滚动

初始“解决方案”

我设法用DragGesture()的{​​{1}}手势实现了所需的动画。

See Example GIF here

这是通过以下代码实现的:

minimumDistance: 0

问题

如果用户从在矩形上用手指开始滚动,它将注册为拖动手势。如果他们开始向其他地方滚动,则滚动会正常进行

See Example GIF here

替代

如果我使用修饰符@State private var pressed: Bool = false var body: some View { let drag = DragGesture(minimumDistance: 0) .onChanged({_ in self.pressed = true }) .onEnded({_ in self.pressed = false }) return ScrollView { Rectangle() .frame(minHeight: 100) .scaleEffect(self.pressed ? 0.5 : 1) .animation(.easeInOut) // .onTapGesture(perform: { // self.pressed.toggle() // }) .gesture(drag) } } ,则可以点击并进行注册,然后开始滚动并根据需要将其注册为滚动

See Example GIF here

这是通过以下代码实现的:

.onTapGesture()

问题

那么如何在允许滚动的同时仍然获得所需的动画?我研究了@State private var pressed: Bool = false var body: some View { let drag = DragGesture(minimumDistance: 0) .onChanged({_ in self.pressed = true }) .onEnded({_ in self.pressed = false }) return ScrollView { Rectangle() .frame(minHeight: 100) .scaleEffect(self.pressed ? 0.5 : 1) .animation(.easeInOut) .onTapGesture(perform: { self.pressed.toggle() }) // .gesture(drag) } } GestureMaskssimultaneousGesture等内容,但它们并没有实现我想要的快速响应动画...

谢谢!

1 个答案:

答案 0 :(得分:2)

设法“大部分”自己修复,发布答案以帮助他人。

这不是完美的,但是更好。如果有人能找到在滚动时不缩小尺寸的方法,那就太好了。但是否则,您可以点击它并在上面滚动即可。

struct ContentView: View {
    @State private var pressed: Bool = false

    var body: some View {
        print(self.pressed)
        return ScrollView {
            Button(action: { self.pressed.toggle() }) {
                Rectangle()
                    .frame(minHeight: 100)
                    .animation(.easeInOut)
            }.buttonStyle(tapBounceButtonStyle())
        }
    }
}

struct tapBounceButtonStyle: ButtonStyle {
  func makeBody(configuration: Self.Configuration) -> some View {
    configuration.label
        .scaleEffect(configuration.isPressed ? 0.9 : 1)
  }
}