![](/img/trans.png)
[英]SwiftUI TapGesture and LongPressGesture in ScrollView with tap indication not working
[英]How can I make a NavigationLink with TapGesture and LongPressGesture working simultaneously together in SwiftUI?
是否可以让 NavigationView 链接与点击手势(onLongPressGesture)共存?
我不能让它为我的生活工作......
ScrollView {
ForEach(self.itemStore.items) { p in
NavigationLink(destination: Details(p: p)) {
CardDetector(p: p, position: self.position)
}
}
}
struct CardDetector: View {
var p: ListData
@State var position: CardPosition
@Namespace var namespace
var body: some View {
Group {
switch position {
case .small:
smallcardView(p: p, namespace: namespace)
.padding()
.frame(maxWidth: .infinity)
.frame(height: 120)
.background(BlurView(style: .regular))
.cornerRadius(10)
.padding(.vertical,6)
.onLongPressGesture {
withAnimation {
position = .big
}
}
.padding(.horizontal)
这会导致滚动问题......他们说解决方案是添加一个onTapGesture
(根据答案: Longpress and list scrolling )但是NavigationLink
不会工作?
解决方案是将链接与手势分开,以编程方式激活链接。 在这种情况下,动作、手势和滚动不会发生冲突。
这是可能方法的简化演示。 使用 Xcode 12.4 / iOS 14.4 测试
struct ContentView: View {
var body: some View {
NavigationView {
List(0..<10) {
LinkCard(number: $0 + 1)
}
}
}
}
struct LinkCard: View {
let number: Int
@State private var isActive = false
@State private var isBig = false
var body: some View {
RoundedRectangle(cornerRadius: 12).fill(Color.yellow)
.frame(height: isBig ? 400 : 100)
.overlay(Text("Card \(number)"))
.background(NavigationLink(
destination: Text("Details \(number)"),
isActive: $isActive) {
EmptyView()
})
.onTapGesture {
isActive.toggle() // << activate link !!
}
.onLongPressGesture {
isBig.toggle() // << alterante action !!
}
}
}
这是一个解释起来很复杂的项目,但我尝试:为了能够直接链接到 View 而不仅仅是简单的String
或Text
,我在我们的Item
结构中定义了符合 View 协议的 Content 类型。 因此,您可以链接您已经设计的任何视图。
为了让 tap 实际上能够打开链接,我们应该使用自定义绑定。
struct ContentView: View {
@State private var items: [Item] = [Item(stringValue: "Link 0", destination: Text("Destination 0").foregroundColor(Color.red)),
Item(stringValue: "Link 1", destination: Text("Destination 1").foregroundColor(Color.green)),
Item(stringValue: "Link 2", destination: Text("Destination 2").foregroundColor(Color.blue))]
var body: some View {
NavigationView {
Form {
ForEach(items.indices, id: \.self ) { index in
NavigationLink(destination: items[index].destination , isActive: Binding.init(get: { () -> Bool in return items[index].isActive },
set: { (newValue) in items[index].isActive = newValue })) {
Color.white.opacity(0.01)
.overlay(Text(items[index].stringValue), alignment: .leading)
.onTapGesture { items[index].isActive.toggle(); print("TapGesture! on Index:", index.description) }
.onLongPressGesture { print("LongPressGesture! on Index:", index.description) }
}
}
}
}
}
}
struct Item<Content: View>: Identifiable {
let id: UUID = UUID()
var stringValue: String
var isActive: Bool = Bool()
var destination: Content
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.