Skip to content

Instantly share code, notes, and snippets.

@gotelgest
Last active February 24, 2024 14:35
Show Gist options
  • Save gotelgest/cf309f6e2095ff22a20b09ba5c95be36 to your computer and use it in GitHub Desktop.
Save gotelgest/cf309f6e2095ff22a20b09ba5c95be36 to your computer and use it in GitHub Desktop.
SearchPushRow for Eureka 4.0.1 (Swift 4)
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
}
@PreetikaSingh
Copy link

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 !

@croese
Copy link

croese commented Jan 14, 2019

@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())
}

@rohitucskm
Copy link

rohitucskm commented Jan 17, 2019

The above code is not compiling on Swift 4.2 and Eureka 4.3. Can anybody help me with this.

@sarbogast
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment