From ee0f1d0ae7e6eb4a2c90d802bbf386b21c7aeab1 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Fri, 17 Oct 2025 20:32:27 +0800 Subject: [PATCH 1/2] feat: implement scroll-to-top for native TabView using Combine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement proper SwiftUI approach for detecting tab reselection: - Add Combine PassthroughSubject to capture all tab taps - Create intermediate binding that publishes tap events - Use onReceive to dispatch TabbarClickAction for scroll-to-top - Works for both tab switches and same-tab taps - Pure SwiftUI solution without UIKit introspection This enables the native iOS behavior where tapping an active tab scrolls content to the top, matching standard iOS app behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- V2er/View/MainPage.swift | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/V2er/View/MainPage.swift b/V2er/View/MainPage.swift index 453ddf1..f04efad 100644 --- a/V2er/View/MainPage.swift +++ b/V2er/View/MainPage.swift @@ -7,9 +7,11 @@ // import SwiftUI +import Combine struct MainPage: StateView { @EnvironmentObject private var store: Store + @State private var tabReselectionPublisher = PassthroughSubject() var bindingState: Binding { $store.appState.globalState @@ -22,10 +24,30 @@ struct MainPage: StateView { store.appState.feedState.feedInfo.unReadNums } + // Create an intermediate binding that captures all tab selections + // This is the proper SwiftUI way to detect same-tab taps without UIKit + private var tabSelection: Binding { + Binding( + get: { selectedTab.wrappedValue }, + set: { newValue in + let currentTab = selectedTab.wrappedValue + + // Publish the tap event before changing the value + // This allows us to detect same-tab taps + tabReselectionPublisher.send(newValue) + + // Update the actual selection + if newValue != currentTab { + selectedTab.wrappedValue = newValue + } + } + ) + } + var body: some View { NavigationView { ZStack { - TabView(selection: selectedTab) { + TabView(selection: tabSelection) { // Feed Tab pageWithTopBar( FeedPage(selecedTab: state.selectedTab) @@ -83,6 +105,10 @@ struct MainPage: StateView { .zIndex(1000) } } + .onReceive(tabReselectionPublisher) { tappedTab in + // Dispatch action for all tab taps (including same-tab taps) + dispatch(TabbarClickAction(selectedTab: tappedTab)) + } .navigationBarHidden(true) } } From 1bea1fb4218e388c5141e83e29303d47a0b43c7d Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Fri, 17 Oct 2025 20:36:45 +0800 Subject: [PATCH 2/2] fix: update tab selection unconditionally for consistency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply Copilot suggestion to always update selectedTab binding value, even when tapping the same tab. This ensures the TabView selection stays in sync and simplifies the binding logic. Setting the same value is harmless in SwiftUI and prevents potential sync issues between the intermediate binding and the actual state. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- V2er/View/MainPage.swift | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/V2er/View/MainPage.swift b/V2er/View/MainPage.swift index f04efad..2a1e8ae 100644 --- a/V2er/View/MainPage.swift +++ b/V2er/View/MainPage.swift @@ -30,16 +30,12 @@ struct MainPage: StateView { Binding( get: { selectedTab.wrappedValue }, set: { newValue in - let currentTab = selectedTab.wrappedValue - // Publish the tap event before changing the value // This allows us to detect same-tab taps tabReselectionPublisher.send(newValue) - // Update the actual selection - if newValue != currentTab { - selectedTab.wrappedValue = newValue - } + // Always update the selection to maintain consistency + selectedTab.wrappedValue = newValue } ) }