Skip to content
This repository has been archived by the owner on Aug 13, 2024. It is now read-only.

Commit

Permalink
feat: add 'searchClicked' callback
Browse files Browse the repository at this point in the history
  • Loading branch information
thislooksfun committed Aug 2, 2020
1 parent 020890e commit 4a5ce7f
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions Sources/SwiftlySearch/SwiftlySearch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import SwiftUI
import Combine

public extension View {
func navigationBarSearch(_ searchText: Binding<String>, placeholder: String? = nil, hidesNavigationBarDuringPresentation: Bool = true, hidesSearchBarWhenScrolling: Bool = true) -> some View {
return overlay(SearchBar<AnyView>(text: searchText, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling).frame(width: 0, height: 0))
func navigationBarSearch(_ searchText: Binding<String>, placeholder: String? = nil, hidesNavigationBarDuringPresentation: Bool = true, hidesSearchBarWhenScrolling: Bool = true, searchClicked: @escaping () -> Void = {}) -> some View {
return overlay(SearchBar<AnyView>(text: searchText, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling, searchClicked: searchClicked).frame(width: 0, height: 0))
}

func navigationBarSearch<ResultContent: View>(_ searchText: Binding<String>, placeholder: String? = nil, hidesNavigationBarDuringPresentation: Bool = true, hidesSearchBarWhenScrolling: Bool = true, @ViewBuilder resultContent: @escaping (String) -> ResultContent) -> some View {
return overlay(SearchBar(text: searchText, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling, resultContent: resultContent).frame(width: 0, height: 0))
func navigationBarSearch<ResultContent: View>(_ searchText: Binding<String>, placeholder: String? = nil, hidesNavigationBarDuringPresentation: Bool = true, hidesSearchBarWhenScrolling: Bool = true, searchClicked: @escaping () -> Void = {}, @ViewBuilder resultContent: @escaping (String) -> ResultContent) -> some View {
return overlay(SearchBar(text: searchText, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling, searchClicked: searchClicked, resultContent: resultContent).frame(width: 0, height: 0))
}
}

Expand All @@ -36,13 +36,15 @@ fileprivate struct SearchBar<ResultContent: View>: UIViewControllerRepresentable
let placeholder: String?
let hidesNavigationBarDuringPresentation: Bool
let hidesSearchBarWhenScrolling: Bool
let searchClicked: () -> Void
let resultContent: (String) -> ResultContent?

init(text: Binding<String>, placeholder: String?, hidesNavigationBarDuringPresentation: Bool, hidesSearchBarWhenScrolling: Bool, @ViewBuilder resultContent: @escaping (String) -> ResultContent? = { _ in nil }) {
init(text: Binding<String>, placeholder: String?, hidesNavigationBarDuringPresentation: Bool, hidesSearchBarWhenScrolling: Bool, searchClicked: @escaping () -> Void, @ViewBuilder resultContent: @escaping (String) -> ResultContent? = { _ in nil }) {
self._text = text
self.placeholder = placeholder
self.hidesNavigationBarDuringPresentation = hidesNavigationBarDuringPresentation
self.hidesSearchBarWhenScrolling = hidesSearchBarWhenScrolling
self.searchClicked = searchClicked
self.resultContent = resultContent
}

Expand All @@ -59,18 +61,20 @@ fileprivate struct SearchBar<ResultContent: View>: UIViewControllerRepresentable
}

func makeCoordinator() -> Coordinator {
return Coordinator(text: $text, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, resultContent: resultContent)
return Coordinator(text: $text, placeholder: placeholder, hidesNavigationBarDuringPresentation: hidesNavigationBarDuringPresentation, resultContent: resultContent, searchClicked: searchClicked)
}

class Coordinator: NSObject, UISearchResultsUpdating {
class Coordinator: NSObject, UISearchResultsUpdating, UISearchBarDelegate {
@Binding
var text: String
let searchClicked: () -> Void
let searchController: UISearchController

private var subscription: AnyCancellable?

init(text: Binding<String>, placeholder: String?, hidesNavigationBarDuringPresentation: Bool, resultContent: (String) -> ResultContent?) {
init(text: Binding<String>, placeholder: String?, hidesNavigationBarDuringPresentation: Bool, resultContent: (String) -> ResultContent?, searchClicked: @escaping () -> Void) {
self._text = text
self.searchClicked = searchClicked

let resultView = resultContent(text.wrappedValue)
let searchResultController = resultView.map { UIHostingController(rootView: $0) }
Expand All @@ -82,6 +86,7 @@ fileprivate struct SearchBar<ResultContent: View>: UIViewControllerRepresentable
searchController.hidesNavigationBarDuringPresentation = hidesNavigationBarDuringPresentation
searchController.obscuresBackgroundDuringPresentation = false

searchController.searchBar.delegate = self
if let placeholder = placeholder {
searchController.searchBar.placeholder = placeholder
}
Expand All @@ -96,12 +101,19 @@ fileprivate struct SearchBar<ResultContent: View>: UIViewControllerRepresentable
self.subscription?.cancel()
}

// MARK: - UISearchResultsUpdating
func updateSearchResults(for searchController: UISearchController) {
guard let text = searchController.searchBar.text else { return }
DispatchQueue.main.async {
self.text = text
}
}


// MARK: - UISearchBarDelegate
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.searchClicked()
}
}

class SearchBarWrapperController: UIViewController {
Expand Down

0 comments on commit 4a5ce7f

Please sign in to comment.