diff --git a/Mlem/Views/Shared/Search Bar/SearchBar.swift b/Mlem/Views/Shared/Search Bar/SearchBar.swift index 71a7ff4bd..2f979ecf0 100644 --- a/Mlem/Views/Shared/Search Bar/SearchBar.swift +++ b/Mlem/Views/Shared/Search Bar/SearchBar.swift @@ -133,19 +133,34 @@ import SwiftUI (uiView as? _UISearchBar)?.isFirstResponderBinding = isFocused do { - if let uiView = uiView as? _UISearchBar, environment.isEnabled { - DispatchQueue.main.async { - if let isFocused, uiView.window != nil { - uiView.isFirstResponderBinding = isFocused - - if isFocused.wrappedValue, !uiView.isFirstResponder { - uiView.becomeFirstResponder() - } else if !isFocused.wrappedValue, uiView.isFirstResponder { - uiView.resignFirstResponder() - } + // version of below with no responder binding. it's not a pretty hack but it does work + // note that switching tabs with search selected will result in search still displaying "search for communities and users," + // but since the keyboard hides the tab bar that probably won't come up for 99% of users + if let isFocused, environment.isEnabled { + if isFocused.wrappedValue, !uiView.isFirstResponder { + DispatchQueue.main.async { + uiView.becomeFirstResponder() + } + } else if !isFocused.wrappedValue, uiView.isFirstResponder { + DispatchQueue.main.async { + uiView.resignFirstResponder() } } } + +// if let uiView = uiView as? _UISearchBar, environment.isEnabled { +// DispatchQueue.main.async { +// if let isFocused, uiView.window != nil { +// uiView.isFirstResponderBinding = isFocused +// +// if isFocused.wrappedValue, !uiView.isFirstResponder { +// uiView.becomeFirstResponder() +// } else if !isFocused.wrappedValue, uiView.isFirstResponder { +// uiView.resignFirstResponder() +// } +// } +// } +// } } } diff --git a/Mlem/Views/Tabs/Search/SearchView.swift b/Mlem/Views/Tabs/Search/SearchView.swift index b10ea7eb5..0dffe8f7a 100644 --- a/Mlem/Views/Tabs/Search/SearchView.swift +++ b/Mlem/Views/Tabs/Search/SearchView.swift @@ -27,6 +27,8 @@ struct SearchView: View { // environment @Environment(\.scrollViewProxy) private var scrollProxy + @Environment(\.navigationPathWithRoutes) private var navigationPath + @Environment(\.tabSelectionHashValue) var tabSelectionHashValue @EnvironmentObject var appState: AppState @EnvironmentObject private var recentSearchesTracker: RecentSearchesTracker @StateObject var searchModel: SearchModel @@ -34,6 +36,7 @@ struct SearchView: View { @StateObject var homeSearchModel: SearchModel @StateObject var homeContentTracker: ContentTracker = .init() + @State var searchBarFocused: Bool = false @State var isSearching: Bool = false @State var page: Page = .home @@ -66,6 +69,7 @@ struct SearchView: View { resultsScrollToTopSignal += 1 recentsScrollToTopSignal += 1 } + .focused($searchBarFocused) } .navigationSearchBarHiddenWhenScrolling(false) .autocorrectionDisabled(true) @@ -85,6 +89,24 @@ struct SearchView: View { resultsScrollToTopSignal += 1 } } + .onChange(of: tabSelectionHashValue) { newValue in + // due to the hack in SearchBar:136, this is required to move focus off of the search bar when changing tabs + // because the keyboard hides the tab bar and so users are required to cancel a search to switch tabs, this + // probably isn't needed in most cases, but since it's possible to disable the on-screen keyboard I've included it + if tabSelectionHashValue == TabSelection.search.hashValue, newValue != TabSelection.search.hashValue { + searchBarFocused = false + } + } + .hoistNavigation { + if scrollToTopAppeared { + searchBarFocused = true + } else { + withAnimation { + scrollToTop(page: page) + } + } + return true + } } @ViewBuilder @@ -146,12 +168,6 @@ struct SearchView: View { } } } - .hoistNavigation { - withAnimation { - scrollToTop(page: page) - } - return true - } } private func scrollToTop(page: Page) {