Быстрая базовая функциональность поиска через раздел в UITableVIew - PullRequest
0 голосов
/ 22 мая 2019

Я разработал свой поисковый компонент на основе этого учебника .

. Он хорошо работает, если у меня есть один раздел в табличном представлении, поэтому мне не нужно беспокоиться о вложенных вещах..

Вот мой код:

import UIKit

protocol Searchable {
    var query: String { get }
    var isSelected: Bool { get set }
}

class BaseSearchDataSource<V, T: Searchable>: NSObject, UITableViewDataSource where V: BaseTableViewCell<T> {

    private var models: [T]
    private let configureCell: CellConfiguration
    typealias CellConfiguration = (V, T) -> V
    private var searchResults: [T] = []
    private var isSearchActive: Bool = false

    init(models: [T], configureCell: @escaping CellConfiguration) {
        self.models = models
        self.configureCell = configureCell
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return isSearchActive ? searchResults.count : models.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: V = tableView.dequeueReusableCell(forIndexPath: indexPath)
        let model = getModelAt(indexPath)
        return configureCell(cell, model)
    }

    func getModelAt(_ indexPath: IndexPath) -> T {
        return isSearchActive ? searchResults[indexPath.item] : models[indexPath.item]
    }

    func search(query: String) {
        isSearchActive = !query.isEmpty
        searchResults = models.filter {
            let queryToFind = $0.query.range(of: query, options: NSString.CompareOptions.caseInsensitive)
            return (queryToFind != nil)
        }
    }
}

У меня есть реализация этого класса, соответствующая указанному протоколу:

class MuscleSelectableItem: Searchable {

var query: String {
    return name
}

var isSelected: Bool

let name: String
let muscle: MusclEntity

init (isSelected: Bool, name: String, muscle: MusclEntity) {
    self.isSelected = isSelected
    self.name = name
    self.muscle = muscle
}
}

Так что теперь, когда я использую свой подкласс:parent BaseSearchDataSource Я могу просто указать класс, который я хочу загрузить в мое табличное представление, и сделать этот класс доступным для поиска.Так что теперь мой var models: [T] представляет модели как [MuscleSelectableItem]

Я понимаю, что мне нужно использовать некоторый объект раздела с вложенными элементами вроде:

class TableViewSection {
var items: [MuscleSelectableItem]
}

Но проблема с кодом вышеЯ указал конкретный тип [MuscleSelectableItem] для items.

Как объявить [T], который будет TableViewSection с items, которые не определены, пока мы не сообщим компилятору в подклассах, какой тип мы хотим использоватьдля items, например для поиска городов, мышц или книг или любых других объектов, поэтому items может быть любым из них

Также мне не нравится, что мой протокол содержит функции поиска и выборакак правильно его отделить?

1 Ответ

1 голос
/ 23 мая 2019

Вы также можете использовать дженерики в своей оболочке.В приведенном выше случае это будет выглядеть так:

class TableViewSection<T> {
    var items = [T]()

}

Вы также можете создать класс TableDataSource, который имеет массив разделов табличного представления, который откроет такие возможности, как подписка на основе indexPath, а затем его соответствиек протоколу сбора, чтобы получить такие функции, как фильтр, счетчик и т. д.

Кроме того, что мне не нравится, так как мой протокол содержит функции поиска и выбора, как их правильно разделить?

Swift позволяет составлять протоколы меньших протоколов с использованием typealiasing.Вышеприведенное можно разделить следующим образом:

protocol Searchable {
    var query: String { get }
}

protocol Selectable {
    var isSelected: Bool { get set }
}

typealias SearchAndSelectable = Searchable & Selectable

Переменная типа SearchAndSelectable будет иметь значения 'query' и 'isSelected', что удобно для общих ограничений или функций, которые могут использовать преимуществаоба типа протокола.

...