Swift 4: Невозможно заставить NSPredicate работать с searchBar и локальной областью - PullRequest
0 голосов
/ 24 октября 2018

Я пытался решить эту проблему в последние часы.Я просто не понимаю, почему это не работает.

Резюме: я хочу отфильтровать локальную область по входу searchBar.Если я устанавливаю предикат в жестком коде, он просто отлично работает, если я передаю searchBar.text в формат предиката, а результаты равны нулю.

✔ Рабочая (жестко закодированная строка):

func updateSearchResults(for searchController: UISearchController) {

    let manualString = "Steven"

    results = results.filter("ID >1 AND name CONTAINS %@", manualString)
    print(results.first)
    tableView.reloadData()

}

Консоль:

6:53:01.262 ViewController.updateSearchResults(): - Optional(colleagues {
    ID = 40;
    quoteText = Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.;
    name = Steven;
    UUID = 3ad52f7e-ad2e-46c4-aace-079c0eb8db17;
    timestamp = 2018-10-24 14:09:16 +0000;
})

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

Working

Теперь я вставляю searchBar.text в мой предикат:

❌ НЕ работает (строка searchBar):

func updateSearchResults(for searchController: UISearchController) {

    results = results.filter("ID >1 AND name CONTAINS %@", searchController.searchBar.text!)

    print(searchController.searchBar.text!)
    print(results.first)
    tableView.reloadData()

}

Консоль:

16: 15: 31.615 ViewController.updateSearchResults () searchBar.text: - Steven

16: 15: 31.615 ViewController.updateSearchResults () результат: - ноль

Nothing

Ничего!

Я не понимаю, я даже проверил тип обоих вариантов с помощью (type (of: T). Оба отображаются в виде строки.

Заранее большое спасибо!





Дополнительная информация:

ViewController.swift (ненужное сокращение):

class Cell: UITableViewCell {
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String!) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
    }

    required init(coder: NSCoder) {
        fatalError("NSCoding not supported")
    }
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var results = realm.objects(colleagues.self).sorted(byKeyPath: "timestamp", ascending: false)
    var notificationToken: NotificationToken?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        searchController.searchResultsUpdater = self
        tableView.tableHeaderView = searchController.searchBar

        setupViews()

        // Set results notification block
        self.notificationToken = results.observe { (changes: RealmCollectionChange) in
            switch changes {
            ...
            }
        }
    }

    let tableView: UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(Cell.self, forCellReuseIdentifier: "cell")

        return tableView
    }()


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return results.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell

        let object ...

        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            realm.beginWrite()
            realm.delete(results[indexPath.row])
            try! realm.commitWrite()
        }
    }

    let searchController = UISearchController(searchResultsController: nil)


    fileprivate func setupViews(){
        ... 
    }
}

extension ViewController: UISearchResultsUpdating {

    func updateSearchResults(for searchController: UISearchController) {

        results = results.filter("ID >1 AND name CONTAINS %@", searchController.searchBar.text!)

        print(searchController.searchBar.text!)
        print(results.first)
        tableView.reloadData()
    }
}

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Попробуйте с кодом ниже

if let searchStr = searchController.searchBar.text {
            results = results.filter("ID >1 AND name CONTAINS %@", searchStr)
}
0 голосов
/ 24 октября 2018

Я думаю, что нашел причину, по которой это не сработало, была моя логическая проблема:

let searchStr = String(format: "%@", searchController.searchBar.text!)
let newResults = results.filter("ID >1 AND author CONTAINS %@", searchStr)
  • Как только я нажму searchBar, переменная results очищается:
    1. Результат будет отфильтрован с помощью "" (пусто)
    2. Теперь пустые отфильтрованные результаты перезаписывают начальный заполненный результат (results = results.filter (...)

Если я перенесу отфильтрованный результат в новый результат, он будет работать!

0 голосов
/ 24 октября 2018

Попробуйте с кодом ниже: -

let searchStr = String(format: "%@", searchController.searchBar.text!)
results = results.filter("ID >1 AND name CONTAINS %@", searchStr)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...