From e20ed28772278630257c4485122f8f09462b60c4 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Sun, 14 Sep 2025 12:18:32 +0800 Subject: [PATCH 1/2] fix: safari view now respects current UI mode (light/dark) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added Environment property to track colorScheme in SafariView - Safari view controller now inherits interface style from root view controller - Properly handles system, light, and dark appearance modes - Sets appropriate tint colors based on effective UI style 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- V2er/General/Extentions.swift | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/V2er/General/Extentions.swift b/V2er/General/Extentions.swift index feaae38..1dbdece 100644 --- a/V2er/General/Extentions.swift +++ b/V2er/General/Extentions.swift @@ -277,11 +277,43 @@ extension URL { // MARK: - Safari View struct SafariView: UIViewControllerRepresentable { let url: URL + @Environment(\.colorScheme) var colorScheme func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController { - return SFSafariViewController(url: url) + let safariVC = SFSafariViewController(url: url) + updateAppearance(safariVC) + return safariVC } func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext) { + updateAppearance(uiViewController) + } + + private func updateAppearance(_ safariVC: SFSafariViewController) { + // Get the actual interface style from the root view controller + let actualStyle = V2erApp.rootViewController?.overrideUserInterfaceStyle ?? .unspecified + + // Apply the appropriate style to Safari view + if actualStyle != .unspecified { + // User has explicitly set light or dark mode + safariVC.overrideUserInterfaceStyle = actualStyle + } else { + // Following system setting - use the current colorScheme + safariVC.overrideUserInterfaceStyle = colorScheme == .dark ? .dark : .light + } + + // Set tint colors based on the effective style + let effectiveStyle = safariVC.overrideUserInterfaceStyle == .dark || + (safariVC.overrideUserInterfaceStyle == .unspecified && colorScheme == .dark) + + if effectiveStyle { + // Dark mode colors + safariVC.preferredControlTintColor = UIColor.systemBlue + safariVC.preferredBarTintColor = UIColor.systemBackground + } else { + // Light mode colors + safariVC.preferredControlTintColor = UIColor.systemBlue + safariVC.preferredBarTintColor = UIColor.systemBackground + } } } From b0333a14fcd280042ae31a6bb0eb6f7c97df16d1 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Sun, 14 Sep 2025 12:24:21 +0800 Subject: [PATCH 2/2] fix: update Settings page to use SafariView for all external links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced WebBrowserView and SafariWebView with direct SafariView usage - Added IdentifiableURL wrapper to support sheet presentation - Eliminated empty intermediate pages when opening external links - All external links now open in SafariView with proper UI mode support 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- V2er/View/Settings/SettingsPage.swift | 74 +++++++++++++++------------ 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/V2er/View/Settings/SettingsPage.swift b/V2er/View/Settings/SettingsPage.swift index e4cec28..8715d11 100644 --- a/V2er/View/Settings/SettingsPage.swift +++ b/V2er/View/Settings/SettingsPage.swift @@ -9,16 +9,26 @@ import SwiftUI import SafariServices +// Wrapper to make URL Identifiable for sheet presentation +struct IdentifiableURL: Identifiable { + let id = UUID() + let url: URL +} + struct SettingsPage: View { @Environment(\.dismiss) var dismiss @State private var showingAlert = false @State var logingOut: Bool = false - + @State private var safariURL: IdentifiableURL? + var body: some View { formView .navBar("设置") + .sheet(item: $safariURL) { item in + SafariView(url: item.url) + } } - + @ViewBuilder private var formView: some View { ScrollView { @@ -26,24 +36,40 @@ struct SettingsPage: View { SectionItemView("外观设置", showDivider: false) .padding(.top, 8) .to { AppearanceSettingView() } - + SectionItemView("通用设置") .to { OtherSettingsView() } + Button { + if let url = URL(string: "https://github.com/v2er-app/iOS/issues") { + safariURL = IdentifiableURL(url: url) + } + } label: { SectionItemView("问题反馈") .padding(.top, 8) - .to { - SafariWebView(url: "https://github.com/v2er-app/iOS/issues") - } + } + + Button { + if let url = URL(string: "https://www.v2ex.com/help") { + safariURL = IdentifiableURL(url: url) + } + } label: { SectionItemView("V2EX帮助") - .to { - WebBrowserView(url: "https://www.v2ex.com/help") - } - SectionItemView("源码开放") - .to { - WebBrowserView(url: "https://github.com/v2er-app") - } + } + Button { + if let url = URL(string: "https://github.com/v2er-app") { + safariURL = IdentifiableURL(url: url) + } + } label: { + SectionItemView("源码开放") + } + + Button { + if let url = URL(string: "https://v2er.app") { + safariURL = IdentifiableURL(url: url) + } + } label: { SectionView("关于") { HStack { Text("版本1.0.0") @@ -55,9 +81,7 @@ struct SettingsPage: View { .padding(.trailing, 16) } } - .to { - WebBrowserView(url: "https://v2er.app") - } + } Button { // "https://github.com/v2er-app".openURL() @@ -108,24 +132,6 @@ struct SettingsPage: View { } } -struct SafariWebView: View { - let url: String - @State private var showingSafari = false - - var body: some View { - Color.clear - .onAppear { - if let url = URL(string: url) { - showingSafari = true - } - } - .sheet(isPresented: $showingSafari) { - if let url = URL(string: url) { - SafariView(url: url) - } - } - } -} struct SettingsPage_Previews: PreviewProvider { static var previews: some View {