fix(mobile): sometimes search requires double taps

This commit is contained in:
Tienson Qin
2025-12-02 14:55:09 +08:00
parent 0d134cb4c5
commit 000280080f
2 changed files with 28 additions and 47 deletions

View File

@@ -114,7 +114,6 @@ private struct LiquidTabs26View: View {
let navController: UINavigationController
@State private var searchText: String = ""
@State private var isSearchPresented: Bool = false
@FocusState private var isSearchFocused: Bool
@State private var hackShowKeyboard: Bool = false
@@ -158,6 +157,13 @@ private struct LiquidTabs26View: View {
return .search
}
private func focusSearchField() {
// Drive focus (and keyboard) only through searchFocused.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
isSearchFocused = true
}
}
var body: some View {
if store.tabs.isEmpty {
// bootstrap webview so JS can configure tabs
@@ -187,7 +193,6 @@ private struct LiquidTabs26View: View {
Tab(value: .search, role: .search) {
SearchTabHost26(
navController: navController,
isSearchFocused: $isSearchFocused,
selectedTab: $selectedTab,
firstTabId: store.tabs.first?.id,
store: store
@@ -196,8 +201,7 @@ private struct LiquidTabs26View: View {
}
}
.searchable(
text: $searchText,
isPresented: $isSearchPresented
text: $searchText
)
.searchFocused($isSearchFocused)
.searchToolbarBehavior(.minimize)
@@ -206,16 +210,13 @@ private struct LiquidTabs26View: View {
}
.background(Color.logseqBackground)
// Hidden UITextField that pre-invokes keyboard
// Hidden UITextField that pre-invokes keyboard (optional)
KeyboardHackField(shouldShow: $hackShowKeyboard)
.frame(width: 0, height: 0)
}
.onAppear {
let initial = initialSelection()
selectedTab = initial
if case .search = initial {
isSearchPresented = true
}
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
@@ -248,23 +249,20 @@ private struct LiquidTabs26View: View {
switch newValue {
case .search:
isSearchPresented = true
case .content:
hackShowKeyboard = false
isSearchFocused = false
isSearchPresented = false
}
}
.onChange(of: isSearchPresented) { presented in
if presented {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
// Every time we switch to the search tab, re-focus the search
// field so the search bar auto-focuses and keyboard appears.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
hackShowKeyboard = true
isSearchFocused = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
hackShowKeyboard = false
}
} else {
focusSearchField()
case .content:
// Leaving search tab drop focus and stop hack keyboard.
isSearchFocused = false
hackShowKeyboard = false
}
@@ -284,11 +282,12 @@ private struct LiquidTabs26View: View {
}
}
// Search host for 26+ (unchanged)
// Search host for 26+
// Only responsible for cancel behaviour and tab switching.
// It does NOT own the focus anymore.
@available(iOS 26.0, *)
private struct SearchTabHost26: View {
let navController: UINavigationController
@FocusState.Binding var isSearchFocused: Bool
var selectedTab: Binding<LiquidTabsTabSelection>
let firstTabId: String?
let store: LiquidTabsStore
@@ -300,14 +299,6 @@ private struct SearchTabHost26: View {
NavigationStack {
NativeNavHost(navController: navController)
.ignoresSafeArea()
.onAppear {
DispatchQueue.main.async {
isSearchFocused = true
}
}
.onDisappear {
isSearchFocused = false
}
.onChange(of: isSearching) { searching in
if searching {
wasSearching = true
@@ -315,7 +306,7 @@ private struct SearchTabHost26: View {
case .search = selectedTab.wrappedValue,
let firstId = firstTabId {
// Cancel logic - Programmatic switch back to first content tab
// User tapped Cancel: switch back to first normal tab.
wasSearching = false
selectedTab.wrappedValue = .content(0)
store.selectedId = firstId
@@ -364,18 +355,6 @@ private struct LiquidTabs16View: View {
store.selectedId = id
LiquidTabsPlugin.shared?.notifyTabSelected(id: id)
}
// Basic keyboard hack when selecting Search tab
if id == "search" {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
hackShowKeyboard = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
hackShowKeyboard = false
}
} else {
hackShowKeyboard = false
}
}
)) {
// --- Normal dynamic tabs ---