【问题标题】:How can I simulate a tap/swipe gesture on some part of the screen programmatically in SwiftUI?如何在 SwiftUI 中以编程方式在屏幕的某些部分模拟点击/滑动手势?
【发布时间】:2021-10-24 01:39:06
【问题描述】:

我有一个 SwiftUI 应用程序,其行为类似于 Tinder(built using this guide - 或参见 source code)。您只需左右滑动一堆卡片。我有一个“竖起大拇指”和“竖起大拇指”按钮作为刷卡的替代品,但是当它们被按下时,我希望它能够将卡片刷掉 for 就像用户刷卡一样自己。

在没有 UIKit 的 SwiftUI 中有什么方法可以做到这一点?

【问题讨论】:

  • 您能发布您的代码以获取上下文吗?链接的文章需要会员资格。
  • @Dmitriy 确定,添加了指向 repo 的链接。

标签: ios swiftui swipe gesture tinder


【解决方案1】:

如果您的拇指向上和向下按钮是CardView 的一部分,那么实现起来将非常简单:只需重复按钮操作内的手势执行的任何代码。大致如下:

                   // CardView.swift

                   Button (action: {
                        // hardcoded for simplicity
                        self.translation = .init(width: 100, height: 0)
                        self.swipeStatus = .like
                        // a hacky way to "wait" for animation to complete
                        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3, execute: {
                            self.onRemove(self.user)
                        })
                    }) {
                        Image(systemName: "hand.thumbsup")
                            .foregroundColor(.green)
                    }

但是,如果您的按钮位于 CardView 之外,我认为您将不得不重新设计您的视图。我首先将swipeStatus@State 转换为@Binding,因此它的值可以从父视图传递下来。然后您需要在ContentView 中声明一个状态变量,然后您可以将其与swipeStatus 绑定绑定在一起。比如:

                                    // ContentView.swift

                                    @State var currentSwipeStatus: LikeDislike = .none
                                    ....
                                    CardView(
                                        swipeStatus: self.users.last == user
                                        ? $currentSwipeStatus
                                        : .constant(.none),
                                         user: user,
                                         onRemove: { removedUser in
                                        self.users.removeAll { $0.id == removedUser.id}
                                        self.swipeStatus = .none
                                    })

在您的卡片视图中,您需要对绑定值的变化做出反应。我只是将onChange 附加到主要的VStack

.onChange(of: swipeStatus) { newState in
                if newState == .like {
                        self.translation = .init(width: 100, height: 0)
                        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3, execute: {
                            self.onRemove(self.user)
                        })
                }
            }

我觉得有一种更优雅的方式来实现这一点。我不是 onRemove 回调、asyncAfter hack 以及它们同时渲染所有卡片的事实的忠实粉丝。 但至少这是一个开始。

【讨论】:

    猜你喜欢
    • 2016-12-21
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多