xmartlabs / Eureka

Elegant iOS form builder in Swift
https://eurekacommunity.github.io
MIT License
11.77k stars 1.33k forks source link

SearchPushRow search bar is overlapping with Navigation bar #1778

Closed ghost closed 5 years ago

ghost commented 5 years ago

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.obscuresBackgroundDuringPresentation = false
        navigationItem.searchController = searchController
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.tintColor = UIColor.white
        searchController.hidesNavigationBarDuringPresentation = false
        let proxy2 = UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self, UINavigationController.self])
        proxy2.defaultTextAttributes = [
            .foregroundColor: UIColor.white
        ]

        definesPresentationContext = true
        self.automaticallyAdjustsScrollViewInsets = false;
        if #available(iOS 11.0, *) {
            navigationItem.searchController = searchController
            searchController.searchBar.barTintColor = UIColor.white
           // self.searchController.searchBar.backgroundColor = UIColor.white
            navigationItem.hidesSearchBarWhenScrolling = false
        } 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 = []
            for section in originalOptions{
                print("section : \(section)")

                currentOptions.append(section.filter { $0.selectableValue?.matchesSearchQuery(query.lowercased()) ?? false })
              //  currentOptions.append(section.filter($))
              //  upComingBookingList.filter { ($0.pnr?.lowercased().contains(searchController.searchBar.text!.lowercased()))! }
            }
        }
        tableView.reloadData()
    }

    override open func viewDidLayoutSubviews() {
        self.searchController.searchBar.sizeToFit()
    }

    open override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return currentOptions[section].count == 0 ? 0 : super.tableView(tableView, heightForHeaderInSection: section)
    }

    open override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return currentOptions[section].count == 0 ? 0 : super.tableView(tableView, heightForFooterInSection: section)
    }

    open override func numberOfSections(in tableView: UITableView) -> Int {
        return currentOptions.count
    }

    open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return currentOptions[section].count
    }

    open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let option = currentOptions[indexPath.section][indexPath.row]
        option.updateCell()
        return option.baseCell
    }

    open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        currentOptions[indexPath.section][indexPath.row].didSelect()
        tableView.deselectRow(at: indexPath, animated: true)
    }

    open override func setupForm(with options: [OptionsRow.OptionsProviderType.Option]) {
        super.setupForm(with: options)
        originalOptions = []
        for section in form.allSections {
            if let allRows = section.map({ $0 }) as? [ListCheckRow<Row.Cell.Value>] {
                originalOptions.append(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
}
ghost commented 5 years ago

image from ios

ghost commented 5 years ago

I used above code, but the search bar is overlapping with navigation. Could you please kindly please me? Thanks in advance!

mtnbarreto commented 5 years ago

Hi @tzzen93 , Which is the ios version that code is running? At first look the code seems ok to me.. Anyway I recommend you to follow some guide on how to integrate the search controller, like https://www.techotopia.com/index.php/Integrating_Search_using_the_iOS_UISearchController

ghost commented 5 years ago

Thank you so much for replying and supporting. I had already solved that issue.