SearchFieldMolteo 0.9.1

SearchFieldMolteo 0.9.1

Molteo-OpenSource维护。



  • 作者:
  • mustii

欢迎使用SearchField

开始使用SearchField框架非常简单,但同时它也提供了一种强大的方式来自定义UI。

简单实现

1- 创建一个符合SearchResults协议的结构体,该结构体应该始终具有一个标题

struct SomeImportantElement: SearchResult {
    var title: String = UUID().uuidString
}

2- 符合protocols将强制您创建以下方法,这些方法是使用SearchField框架的最低要求

class OurMainViewController: UIViewController, SearchViewControllerDelegate, SearchViewDelegate {}
protocol SearchViewDelegate {
    func presentSearchViewController()
}
protocol SearchViewDelegate {
    func removeControllerFromView(_ controller: UIViewController)
    func selected(searchResult: SearchResult)
}

3- 框架附带一个SearchFieldView,可以用来展示SearchResult并打开SearchViewController,您可以在视图中任何位置将其锚定,并实现SearchViewDelegate所需的方法。`OurMainViewController`还应实现SearchViewController所需的方法以选择元素和关闭视图。

动画由FadingAnimation类处理,该类通过实施的淡入淡出效果呈现和关闭SearchViewController(也可以创建自定义动画并将其发送到transitioningDelegate)。

private var animation = FadingAnimation()

var someArray = [        
    SomeImportantElement(),
    SomeImportantElement(),
    SomeImportantElement(),
]

func presentSearchViewController() {
    // Using the Generic Cell for our SomeImportantElement struct and also conforming the SearchView to it too
    let controller = SearchViewController<GenericCell<SomeImportantElement>, SomeImportantElement>()
    // adding the padding that we want to the results Controller
    controller.resultsControllerPadding = .init(top: 10, left: 20, bottom: 10, right: 20)
    controller.delegate = self
    controller.transitioningDelegate = animation   
    controller.modalPresentationStyle = .currentContext     
    controller.searchableElements = someArray
    present(controller, animated: true)
}

请注意,过滤是在SearchViewController中完成的,因为我们没有实现以下协议SearchViewControllerDataSource

4- 实现所选方法,并实施一个将控制器从视图中移除的方法以关闭视图

    func selected(searchResult: SearchResult) {
        // Do something important
        print(searchResult)
    }

    func removeControllerFromView(_ controller: UIViewController)  {
        controller.dismiss(animated: true)
    }

然后您就完成了🥳🥳!

5- 如果您想实现自己的DataSource,例如网络调用或一些不需要控制器处理的神奇调用,您可以在`OurMainViewController`中设置数据源代理SearchViewControllerDataSource

private var searchController: SearchViewController<GenericCell<SomeImportantElement>, SomeImportantElement>

func presentSearchViewController() {
    /// Code from above
    controller.delegate = self
    controller.dataSource = self
    searchController = controller
    /// Code from above
}

现在,由于您可以实现`filter`方法

func filter(text: String?) {
    guard let txt = text, !txt.isEmpty else {
        // Implement your own way to handle empty Text or might be cool to also implement this with a custom SearchResultsController more on how to do that in Section 2 part 2 of this readme
        searchController?.searchableElements = someArray
        return
    }
    // Filtering from someArray or a networking call and setting it to searchableElements
    let filtered = someArray.filter { (id) -> Bool in
        return id.title.contains(txt)
    }
    searchController?.searchableElements = filtered
}

一些自定义实现

想要实现一个自定义的单元格,包含一些自定义元素,比如文本、描述以及可能还有图片吗?

1- 例如,现在我们老板想要一个紫色的单元格,但我们真的无法通过当前的实现达到这个效果。这就是我们为什么从创建这个框架开始...

创建一个自定义的结构体来存储你想要的数据

class ClassifiedStruct: SearchResult {
    var title: String = UUID().uuidString
    var image: UIImage?
    var betterTitle: String = "Hello 🐩!"
}

为你要展示的数据创建一个自定义的 GenericCell

class SomeReallyClassifiedImplementation: GenericCell<ClassifiedStruct> {

    // <<<HERE COMES YOUR CUSTOM UI IMPLEMENTATION>>>

    override var item: Element? {
        didSet {
            guard let item = item else { return }
            superAwesomeTitle.text = betterTitle
            poodleImageView.setImage(item.image)
        }
    }

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        backgroundColor = .purple
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

2- 如果你对我们对 UITableView 的实现不满意,你可以通过继承 SearchResultsController 来实现自己的实现。但是有一些限制,比如你将无法实现分区。你只能实现头部和尾部视图。

class SomeController: SearchResultsController<TestCell, Test> {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        // YOU CAN return a custom header
        let view = UIView()
        view.backgroundColor = .red
        return view
    }

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        // we return a header in this case when there are zero filtered items
        return count == 0 ? 250 : 0
    }
}