【问题标题】:SwiftUI TapGesture and LongPressGesture in ScrollView with tap indication not workingScrollView中的SwiftUI TapGesture和LongPressGesture,点击指示不起作用
【发布时间】:2020-10-25 06:05:36
【问题描述】:

我正在努力在 ScrollView 中同时实现 TapGestureLongPressGesture.onTapGesture.onLongPressGesture 一切正常,但我希望当用户点击按钮时,按钮的不透明度会降低,就像普通的 Button() 一样。

但是,无论出于何种原因,Button() 都无法选择在长按时执行某项操作。所以我尝试使用.gesture(LongPressGesture() ... )。这种方法有效并显示了点击指示。不幸的是,这不适用于ScrollView:你不能再滚动它了!

所以我做了一些研究,发现在LongPressGesture 之前必须有一个 TapGesture,这样ScrollView 才能正常工作。确实是这样,但是我的LongPressGesture 不再起作用了。

希望有人有解决方案...


struct ContentView: View {
    var body: some View {
        ScrollView(.horizontal){
            HStack{
                ForEach(0..<5){ _ in
                    Button()
                }
            }
        }
    }
}

struct Button: View{
    
    @GestureState var isDetectingLongPress = false
    @State var completedLongPress = false
    
    var body: some View{
        
        Circle()
            .foregroundColor(.red)
            .frame(width: 100, height: 100)
            .opacity(self.isDetectingLongPress ? 0 : 1)
            
            // That works, but there is no indication for the user that the UI recognized the gesture
            //                        .onTapGesture {
            //                            print("Tapped!")
            //                       }
            //                        .onLongPressGesture(minimumDuration: 0.5){
            //                            print("Long pressed!")
            //                        }
            
            
            // The approach (*) shows the press indication, but the ScrollView is stuck because there is no TapGesture
            
            // If I add a dummy TapGesture, the LongPressGesture won't work anymore but now the ScrollView works as expected
            //.onTapGesture {}
            
            // (*)
            .gesture(LongPressGesture()
                .updating(self.$isDetectingLongPress) { currentstate, gestureState,
                    transaction in
                    gestureState = currentstate
            }
            .onEnded { finished in
                self.completedLongPress = finished
                }
        )
    }
}

【问题讨论】:

    标签: ios swift xcode swiftui


    【解决方案1】:

    我已经尝试了许多尝试 onTapGesture + LongPressGesture + 自定义时间和动画的组合,并且许多工作/几乎/但留下了一些小烦恼。这就是我发现的完美工作。在 iOS 13.6 上测试。

    使用此解决方案,您的滚动视图仍会滚动,您会看到按钮按下动画,长按按钮也可以。

    struct MainView: View {
        ...
        Scrollview {
            RowView().highPriorityGesture(TapGesture()
                                            .onEnded { _ in
                // The function you would expect to call in a button tap here.
            })
            
        }
    }
    
    struct RowView: View {
        
        @State var longPress = false
        var body: some View {
            Button(action: {
                if (self.longPress) {
                    self.longPress.toggle()
                } else {
                    // Normal button code here
                }
            }) {
                // Buttons LaF here
            }
            // RowView code here.
            .simultaneousGesture(LongPressGesture(minimumDuration: 0.5)
                                    .onEnded { _ in
                self.longPress = true
            })
        }
    }
    

    【讨论】:

    • 谢谢!不错的解决方案!对我也有用:)
    • 如果该项目在 ScrollView 中并且您希望该项目也具有 LongTap 功能怎么样......这似乎是苹果无法弄清楚的事情,因为它仍然很出色!?
    • @Learn2Code 如果您交换 .simultaneosGesture 和 .highPriorityGesture 的位置,那么它将使用两个相同的手势
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2021-02-04
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多