From ac87a4417de91df4ee440160a3301403812edc0f Mon Sep 17 00:00:00 2001 From: vgearen Date: Tue, 31 Mar 2026 11:08:50 +0800 Subject: [PATCH] v1.2.4: Fix scroll position: preserve on chart return, reset on panel reopen - Use ZStack overlay for chart instead of if/else branch swap - ScrollView stays mounted while chart is shown (opacity toggle) - Scroll position preserved when returning from chart view - Panel reopen naturally starts from top Co-Authored-By: Claude Opus 4.6 (1M context) --- StockMonitor.xcodeproj/project.pbxproj | 8 ++--- StockMonitor/Views/DropdownView.swift | 47 ++++++++++++-------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/StockMonitor.xcodeproj/project.pbxproj b/StockMonitor.xcodeproj/project.pbxproj index bf0cfd5..1299494 100644 --- a/StockMonitor.xcodeproj/project.pbxproj +++ b/StockMonitor.xcodeproj/project.pbxproj @@ -339,7 +339,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 1.2.3; + MARKETING_VERSION = 1.2.4; PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.Stockbar; PRODUCT_NAME = "$(TARGET_NAME)"; REGISTER_APP_GROUPS = YES; @@ -373,7 +373,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 1.2.3; + MARKETING_VERSION = 1.2.4; PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.Stockbar; PRODUCT_NAME = "$(TARGET_NAME)"; REGISTER_APP_GROUPS = YES; @@ -393,7 +393,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.2.3; + MARKETING_VERSION = 1.2.4; PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.StockbarTests; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = NO; @@ -412,7 +412,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.2.3; + MARKETING_VERSION = 1.2.4; PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.StockbarTests; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = NO; diff --git a/StockMonitor/Views/DropdownView.swift b/StockMonitor/Views/DropdownView.swift index bd2a4bd..df12fcc 100644 --- a/StockMonitor/Views/DropdownView.swift +++ b/StockMonitor/Views/DropdownView.swift @@ -5,7 +5,6 @@ struct DropdownView: View { @State private var showSettings = false @State private var sortByChange = false @State private var selectedStock: Stock? = nil - @State private var lastSelectedStockId: String? = nil /// 分组数据:(market, stocks, customTitle?) private var groupedStocks: [(Market, [Stock], String?)] { @@ -51,6 +50,21 @@ struct DropdownView: View { return result } + private var stockListView: some View { + ScrollView { + VStack(alignment: .leading, spacing: 6) { + ForEach(Array(groupedStocks.enumerated()), id: \.offset) { _, group in + StockGroupView(market: group.0, stocks: group.1, + title: group.2, + onSelect: { selectedStock = $0 }) + } + } + .padding(.horizontal, 6) + } + .scrollIndicators(.never) + .frame(maxHeight: 520) + } + private func sortValue(quote: Quote?, market: Market, mode: USPriceMode) -> Double { guard let q = quote else { return -Double.infinity } if market == .usStock && mode == .sessionPrice, let ext = q.extendedPrice { @@ -67,37 +81,18 @@ struct DropdownView: View { } else { ProfitSummaryView() - if let stock = selectedStock { - StockChartView(stock: stock, onClose: { selectedStock = nil }) - } else if appState.stocks.isEmpty { + if appState.stocks.isEmpty { Text("暂无股票,点击设置添加") .font(.system(size: 12)) .foregroundColor(.secondary) .frame(maxWidth: .infinity) .padding() } else { - ScrollViewReader { proxy in - ScrollView { - VStack(alignment: .leading, spacing: 6) { - ForEach(Array(groupedStocks.enumerated()), id: \.offset) { _, group in - StockGroupView(market: group.0, stocks: group.1, - title: group.2, - onSelect: { - lastSelectedStockId = $0.id - selectedStock = $0 - }) - } - } - .padding(.horizontal, 6) - } - .scrollIndicators(.never) - .frame(maxHeight: 520) - .onAppear { - if let id = lastSelectedStockId { - DispatchQueue.main.async { - proxy.scrollTo(id, anchor: .center) - } - } + ZStack { + stockListView + .opacity(selectedStock == nil ? 1 : 0) + if let stock = selectedStock { + StockChartView(stock: stock, onClose: { selectedStock = nil }) } } }