ios - 如何在 SwiftUI 中以编程方式在屏幕的某些部分模拟点击/滑动手势?
问题描述
我有一个 SwiftUI 应用程序,其行为类似于 Tinder(使用本指南构建- 或查看源代码)。您只需左右滑动一堆卡片。我有一个“竖起大拇指”和“竖起大拇指”按钮作为刷卡的替代品,但是当它们被按下时,我希望它为用户刷卡,就好像他们自己刷卡一样。
在没有 UIKit 的 SwiftUI 中有什么方法可以做到这一点?
解决方案
If your thumbs up and down buttons were part of the CardView
then it would be quite simple to achieve: just repeat whatever code executes on gesture inside a button action. Something along these lines:
// 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)
}
But, if your buttons reside outside of the CardView
, I think you'll have to re-architect your views a little bit. I would start by converting swipeStatus
from @State
into a @Binding
, so its value can be passed down from the parent view. Then you will need to declare a state variable in your ContentView
, which you can then tie together with swipeStatus
binding. Something like:
// 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
})
Within your card view you'll need to react to the bound value changing. I just appended onChange
to the main 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)
})
}
}
I feel like there's a more elegant way of achieving this. I'm not a big fan of the onRemove
callback, asyncAfter
hack, and the fact that they render all cards at once.
But at least that's a start.
推荐阅读
- attachment - 有没有办法一次保存收到的电子邮件+附件?
- sql - SQL 报表过滤,结果在第一项之后停止
- jquery - free-jqgrid - getRowData 为不在当前页面内的行返回空
- php - 从 PHP 运行屏幕并使用东西
- javascript - JavaScript - 当 if 语句为真时,代码不执行?
- java - 处理 Firebase 中的用户存在
- java - 图像未显示在 JFrame 中
- visual-studio - 一些 Visual Studio 文件的 lint 会根据它们的创建方式而有所不同,即使它们最终完全相同。为什么?
- python - 添加python循环最佳实践
- android - 在电视频道上同时打开 Android TV 应用