mirror of
https://github.com/yattee/yattee.git
synced 2025-12-14 12:08:15 +00:00
Fix iPad iOS 18 keyboard dismissal issue in search
Removed auto-focus logic that was causing keyboard show/hide loop on iPad with docked keyboard. The keyboard was repeatedly dismissing immediately after appearing due to interaction between keyboard notifications, focus state changes, and view updates. Changes: - Removed focused state and keyboard observer from SearchModel - Removed iOS textField reference (kept macOS only) - Removed auto-focus logic from FocusableSearchTextField on iOS - Cleaned up unused focus-related code The search field now works reliably when tapped manually on iPad. Auto-focus still works on macOS where it doesn't cause issues.
This commit is contained in:
@@ -318,7 +318,7 @@ final class NavigationModel: ObservableObject {
|
|||||||
func multipleTapHandler() {
|
func multipleTapHandler() {
|
||||||
switch tabSelection {
|
switch tabSelection {
|
||||||
case .search:
|
case .search:
|
||||||
search.focused = true
|
break
|
||||||
default:
|
default:
|
||||||
print("not implemented")
|
print("not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,9 @@ final class SearchModel: ObservableObject {
|
|||||||
@Published var querySuggestions = [String]()
|
@Published var querySuggestions = [String]()
|
||||||
private var suggestionsDebouncer = Debouncer(.milliseconds(200))
|
private var suggestionsDebouncer = Debouncer(.milliseconds(200))
|
||||||
|
|
||||||
@Published var focused = false
|
|
||||||
|
|
||||||
@Default(.showSearchSuggestions) private var showSearchSuggestions
|
@Default(.showSearchSuggestions) private var showSearchSuggestions
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(macOS)
|
||||||
var textField: UITextField!
|
|
||||||
#elseif os(macOS)
|
|
||||||
var textField: NSTextField!
|
var textField: NSTextField!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -30,15 +26,9 @@ final class SearchModel: ObservableObject {
|
|||||||
private var resource: Resource!
|
private var resource: Resource!
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
#if os(iOS)
|
|
||||||
addKeyboardDidHideNotificationObserver()
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
#if os(iOS)
|
|
||||||
removeKeyboardDidHideNotificationObserver()
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var isLoading: Bool {
|
var isLoading: Bool {
|
||||||
@@ -158,18 +148,4 @@ final class SearchModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
private func addKeyboardDidHideNotificationObserver() {
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDidHide), name: UIResponder.keyboardDidHideNotification, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onKeyboardDidHide() {
|
|
||||||
focused = false
|
|
||||||
}
|
|
||||||
|
|
||||||
private func removeKeyboardDidHideNotificationObserver() {
|
|
||||||
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidHideNotification, object: nil)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,27 +3,15 @@ import SwiftUI
|
|||||||
import SwiftUIIntrospect
|
import SwiftUIIntrospect
|
||||||
|
|
||||||
struct FocusableSearchTextField: View {
|
struct FocusableSearchTextField: View {
|
||||||
@ObservedObject private var state = SearchModel.shared
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
SearchTextField()
|
SearchTextField()
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.introspect(.textField, on: .macOS(.v12, .v13, .v14, .v15)) { textField in
|
.introspect(.textField, on: .macOS(.v12, .v13, .v14, .v15)) { textField in
|
||||||
state.textField = textField
|
SearchModel.shared.textField = textField
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
state.textField?.becomeFirstResponder()
|
SearchModel.shared.textField?.becomeFirstResponder()
|
||||||
}
|
|
||||||
}
|
|
||||||
#elseif os(iOS)
|
|
||||||
.introspect(.textField, on: .iOS(.v15, .v16, .v17, .v18)) { textField in
|
|
||||||
state.textField = textField
|
|
||||||
}
|
|
||||||
.onChange(of: state.focused) { newValue in
|
|
||||||
if newValue, let textField = state.textField, !textField.isFirstResponder {
|
|
||||||
textField.becomeFirstResponder()
|
|
||||||
textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ struct SearchTextField: View {
|
|||||||
TextField("Search...", text: $state.queryText) {
|
TextField("Search...", text: $state.queryText) {
|
||||||
state.changeQuery { query in
|
state.changeQuery { query in
|
||||||
query.query = state.queryText
|
query.query = state.queryText
|
||||||
navigation.hideKeyboard()
|
|
||||||
}
|
}
|
||||||
RecentsModel.shared.addQuery(state.queryText)
|
RecentsModel.shared.addQuery(state.queryText)
|
||||||
|
navigation.hideKeyboard()
|
||||||
}
|
}
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.textFieldStyle(.plain)
|
.textFieldStyle(.plain)
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ struct SearchView: View {
|
|||||||
.opacity(state.queryText.isEmpty ? 0 : 1)
|
.opacity(state.queryText.isEmpty ? 0 : 1)
|
||||||
} else {
|
} else {
|
||||||
results
|
results
|
||||||
|
.backport
|
||||||
|
.scrollDismissesKeyboardInteractively()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.backport
|
|
||||||
.scrollDismissesKeyboardInteractively()
|
|
||||||
}
|
}
|
||||||
.environment(\.listingStyle, searchListingStyle)
|
.environment(\.listingStyle, searchListingStyle)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
|||||||
Reference in New Issue
Block a user