-
-
Save gotelgest/cf309f6e2095ff22a20b09ba5c95be36 to your computer and use it in GitHub Desktop.
import Eureka | |
open class _SearchSelectorViewController<Row: SelectableRowType, OptionsRow: OptionsProviderRow>: SelectorViewController<OptionsRow>, UISearchResultsUpdating where Row.Cell.Value: SearchItem { | |
let searchController = UISearchController(searchResultsController: nil) | |
var originalOptions = [ListCheckRow<Row.Cell.Value>]() | |
var currentOptions = [ListCheckRow<Row.Cell.Value>]() | |
open override func viewDidLoad() { | |
super.viewDidLoad() | |
searchController.searchResultsUpdater = self | |
searchController.dimsBackgroundDuringPresentation = false | |
definesPresentationContext = true | |
if #available(iOS 11.0, *) { | |
navigationItem.searchController = searchController | |
navigationItem.hidesSearchBarWhenScrolling = true | |
} else { | |
tableView.tableHeaderView = searchController.searchBar | |
} | |
} | |
public func updateSearchResults(for searchController: UISearchController) { | |
guard let query = searchController.searchBar.text else { return } | |
if query.isEmpty { | |
currentOptions = originalOptions | |
} else { | |
currentOptions = originalOptions.filter { $0.selectableValue?.matchesSearchQuery(query) ?? false } | |
} | |
tableView.reloadData() | |
} | |
open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return currentOptions.count | |
} | |
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let option = currentOptions[indexPath.row] | |
option.updateCell() | |
return option.baseCell | |
} | |
open override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { | |
return nil | |
} | |
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
currentOptions[indexPath.row].didSelect() | |
tableView.deselectRow(at: indexPath, animated: true) | |
} | |
open override func setupForm(with options: [OptionsRow.OptionsProviderType.Option]) { | |
super.setupForm(with: options) | |
if let allRows = form.first?.map({ $0 }) as? [ListCheckRow<Row.Cell.Value>] { | |
originalOptions = allRows | |
currentOptions = originalOptions | |
} | |
tableView.reloadData() | |
} | |
} | |
open class SearchSelectorViewController<OptionsRow: OptionsProviderRow>: _SearchSelectorViewController<ListCheckRow<OptionsRow.OptionsProviderType.Option>, OptionsRow> where OptionsRow.OptionsProviderType.Option: SearchItem { | |
} | |
open class _SearchPushRow<Cell: CellType> : SelectorRow<Cell> where Cell: BaseCell, Cell.Value : SearchItem { | |
public required init(tag: String?) { | |
super.init(tag: tag) | |
presentationMode = .show(controllerProvider: ControllerProvider.callback { return SearchSelectorViewController<SelectorRow<Cell>> { _ in } }, onDismiss: { vc in | |
let _ = vc.navigationController?.popViewController(animated: true) }) | |
} | |
} | |
public final class SearchPushRow<T: Equatable> : _SearchPushRow<PushSelectorCell<T>>, RowType where T: SearchItem { | |
public required init(tag: String?) { | |
super.init(tag: tag) | |
} | |
} | |
public protocol SearchItem { | |
func matchesSearchQuery(_ query: String) -> Bool | |
} |
Hey thanks for sharing . It worked like a charm. Can we implement case-Insensitive search on this? Please suggest the steps or example if any !
@PreetikaSingh I'm using the matchesSearchQuery
method on my SearchItem
implementer (the Project
struct) to do the case-insensitive matching. You can see this in the "Example code" section:
func matchesSearchQuery(_ query: String) -> Bool {
return id.lowercased().contains(query.lowercased())
}
The above code is not compiling on Swift 4.2 and Eureka 4.3. Can anybody help me with this.
Did anybody manage to get a version of this to work with both sectionKeyForValue (@benji101 version) and lazy loading? Because when I lazy load in @benji101's version I get a crash:
'NSInternalInconsistencyException', reason: 'attempt to insert section 0 but there are only 0 sections after the update'
And I can't figure out how to fix it.
Here is a version of of this code with the ability to use scope filters in the
UISearchController
Example code: