ios SwiftUI TabView -连续点击后在子视图中运行代码

nbnkbykc  于 2023-01-14  发布在  iOS
关注(0)|答案(1)|浏览(106)

我尝试在TabView中实现用户多次点击同一选项卡时的行为,例如在iOS AppStore应用中。第一次点击:切换到视图,第二次点击:弹到根音,第三次轻敲:如果需要,滚动到顶部。
下面的代码可以很好地进行切换,并且每次点击都会调用didTap()

import SwiftUI

enum Tab: String {
    case one
    case two
}

struct AppView: View {
    @State private var activeTab = Tab.one

    var body: some View {
        TabView(selection: $activeTab.onChange(didTap)) {
            One()
                .tabItem {
                    Label("one", systemImage: "1.lane")
                }
                .tag(Tab.one)

            Two()
                .tabItem {
                    Label("two", systemImage: "2.lane")
                }
                .tag(Tab.two)
        }
    }
    
    func didTap(to value: Tab) {
        print(value) // this captures every tap
    }
}

extension Binding {
    func onChange(_ handler: @escaping (Value) -> Void) -> Binding<Value> {
        Binding(
            get: { self.wrappedValue },
            set: { newValue in
                self.wrappedValue = newValue
                handler(newValue)
            }
        )
    }
}

我正在纠结的是,如何告诉OneTwo它被点击了第二次或第三次?(如何弹出和滚动不是问题所在)。
我看到过这个:TabView, tabItem: running code on selection or adding an onTapGesture,但它没有解释如何在其中一个视图中运行代码。
有什么建议吗?

huus2vyu

huus2vyu1#

你可以在一个数组中记录额外的点击(相同值)。数组计数给你在同一个标签上的点击数。

EDIT:现在具有显式子视图结构。

struct ContentView: View {
    
    @State private var activeTab = Tab.one

    @State private var tapState: [Tab] = [Tab.one] // because .one is default
    
    var body: some View {
        TabView(selection: $activeTab.onChange(didTap)) {
            
            SubView(title: "One", tapCount: tapState.count)
                .tabItem {
                    Label("one", systemImage: "1.lane")
                }
                .tag(Tab.one)

            SubView(title: "Two", tapCount: tapState.count)
                .tabItem {
                    Label("two", systemImage: "2.lane")
                }
                .tag(Tab.two)
        }
    }
    
    func didTap(to value: Tab) {
        print(value) // this captures every tap
        if tapState.last == value {
            tapState.append(value) // apped next tap if same value
            print("tapped \(tapState.count) times")
        } else {
            tapState = [value] // reset tap state to new tab selection
        }
    }
}

struct SubView: View {
    
    let title: String
    let tapCount: Int
    
    var body: some View {
        VStack {
            Text("Subview \(title)").font(.title)
            Text("tapped \(tapCount) times")
        }
    }
}

相关问题