Skip to content

Instantly share code, notes, and snippets.

@marcoarment
Created July 11, 2023 19:23
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marcoarment/19318a17ede162b4de5c853f49ca482c to your computer and use it in GitHub Desktop.
Save marcoarment/19318a17ede162b4de5c853f49ca482c to your computer and use it in GitHub Desktop.
Backporting iOS 17's SwiftUI .searchable($isPresented) binding for iOS 16
import SwiftUI
extension View {
public func searchable_iOS16(text: Binding<String>, isPresented: Binding<Bool>, placement: SearchFieldPlacement) -> some View {
modifier(Searchable_iOS16(text: text, isPresented: isPresented, placement: placement))
}
}
public struct Searchable_iOS16: ViewModifier {
@Binding var text: String
@Binding var isPresented: Bool
@State var legacyIsSearching = false
var placement: SearchFieldPlacement
public func body(content: Content) -> some View {
#if os(watchOS) || os(tvOS)
bodyLegacy(content)
#else
if #available(iOS 17, macOS 14, *) {
bodyModern(content)
} else {
bodyLegacy(content)
}
#endif
}
@available(iOS 17, macOS 14, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
public func bodyModern(_ content: Content) -> some View {
content
.searchable(text: $text, isPresented: $isPresented, placement: placement)
}
public func bodyLegacy(_ content: Content) -> some View {
SearchableInner_iOS16(legacyIsSearching: $legacyIsSearching) {
content
}
.searchable(text: $text, placement: placement)
.onChange(of: legacyIsSearching) { isPresented = $0 }
.onAppear { isPresented = legacyIsSearching }
}
}
struct SearchableInner_iOS16<Content: View>: View {
@Environment(\.isSearching) private var environmentIsSearching
@Binding var legacyIsSearching: Bool
var content: () -> Content
init(legacyIsSearching: Binding<Bool>, @ViewBuilder content: @escaping () -> Content) {
self._legacyIsSearching = legacyIsSearching
self.content = content
}
var body: some View {
content()
.onChange(of: environmentIsSearching) { legacyIsSearching = $0 }
.onAppear { legacyIsSearching = environmentIsSearching }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment