使用 .gesture(LongPressGesture) 打破 Scrollview

发布于 2025-01-10 08:16:43 字数 1447 浏览 0 评论 0原文

我在 Xcode 13.2 上使用 Swift 5、SwiftUI 3.0。

我有以下代码:

  ZStack { ... custom button }
 .gesture(LongPressGesture(minimumDuration: 0.5, maximumDistance: 30)
        .onEnded { _ in
                withAnimation(.easeInOut(duration: 1.0)) {
                    // code when ended...
                }
        }
        .onChanged { _ in
            withAnimation(.easeInOut(duration: 0.2)) {
                // code when touched...
            }
            
        })

我们称之为 CustomButton

然后我有了这个 ScrollView 和 LazyVGrid:

ScrollView {
    VStack(spacing: 15) {
           let columns = Array(repeating: GridItem(.flexible(), spacing: 10), count: 1)

           LazyVGrid(columns: columns,spacing: 15) {
               CustomButton()
               CustomButton()
               // and then some more...
           }
    } 
}

现在,当我从 CustomButton 中删除 onChange 处理程序时,滚动工作正常。所以我猜测,由于 onChange() 在我点击按钮时立即触发,因此它优先于 ScrollView。但是,我需要在触发 onChange() 后或用户触摸按钮后发生的动画。

我尝试在 .gesture() 修饰符之前添加一个空的 .onTapGesture {} 。 我尝试将 .gesture 更改为 .simulatenousGesture 我已经尝试了在 SO 或 AppleDev 论坛上可以找到的大部分内容。

我想知道 ScrollView 中是否可以有一个按钮,即:

  1. 接受 0.0 minimumDuration 触摸,或 .gesture().onChange
  2. 在 ScrollView 中仍然可滚动

任何帮助将不胜感激,谢谢!

I'm using Swift 5, SwiftUI 3.0 on Xcode 13.2.

I have the following code:

  ZStack { ... custom button }
 .gesture(LongPressGesture(minimumDuration: 0.5, maximumDistance: 30)
        .onEnded { _ in
                withAnimation(.easeInOut(duration: 1.0)) {
                    // code when ended...
                }
        }
        .onChanged { _ in
            withAnimation(.easeInOut(duration: 0.2)) {
                // code when touched...
            }
            
        })

Let's call this CustomButton.

I then have this ScrollView and LazyVGrid:

ScrollView {
    VStack(spacing: 15) {
           let columns = Array(repeating: GridItem(.flexible(), spacing: 10), count: 1)

           LazyVGrid(columns: columns,spacing: 15) {
               CustomButton()
               CustomButton()
               // and then some more...
           }
    } 
}

Now when I remove the onChange handler from CustomButton, the scrolling works fine. So I am guessing, that since onChange() fires as soon as I tap the button, it takes precedence over the ScrollView. However, I need the animation that occurs after onChange() is fired, or after the user touches the button.

I've tried having an empty .onTapGesture {} before the .gesture() modifier.
I've tried changing .gesture to .simulatenousGesture
And I've tried most anything I can find on SO or the AppleDev forums.

I'm wondering if it's possible to have a button in a ScrollView, that:

  1. Accepts 0.0 minimumDuration touch, or .gesture().onChange
  2. Is still scrollable in ScrollView

Any help would be greatly appreciated, thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岛歌少女 2025-01-17 08:16:43

这种变化有效(不要问我为什么......):

struct CustomButton: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 15)
            .frame(height: 50)
        
            .onTapGesture {
                print("tapped")
            }
        
            .onLongPressGesture(minimumDuration: 0.5, maximumDistance: 30) {
                print("longpress ended")
            } onPressingChanged: { pressing in
                print("longpress changed")
            }
    }
}

This variation works (don't ask me why...):

struct CustomButton: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 15)
            .frame(height: 50)
        
            .onTapGesture {
                print("tapped")
            }
        
            .onLongPressGesture(minimumDuration: 0.5, maximumDistance: 30) {
                print("longpress ended")
            } onPressingChanged: { pressing in
                print("longpress changed")
            }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文