2015-09-16 2 views
0

Я пытаюсь реализовать функцию поиска в этом приложении iOS довольно долгое время.Функция поиска в UISearchBar не работает

У меня есть файл JSON, содержащий все данные, которые затем вытягиваются и отображаются на контроллере табличного представления.

Я реализовал панель поиска и последовали несколько учебников, это один из них с наименьшим количеством проблем - http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift (я также использовал это тоже ранее - https://www.youtube.com/watch?v=N9wcKc37ZXI)

Мой файл JSON структурирована следующим образом:

{ "animal":[ 

    { 
     "no":"001", 
     "type":"dog", 
     "breed":"pitbull", 
     "classification":"mammal", 
     "sprite":"beast" 
    }, 
    { 
     "no":"002", 
     "type":"dog", 
     "breed":"bulldog", 
     "classification":"mammal", 
     "sprite":"beast" 
    }, 
    { 
     "no":"003", 
     "type":"cat", 
     "breed":"birman", 
     "classification":"mammal", 
     "sprite":"feline" 
    } 

]} 

Я зову данные в формате JSON, используя структуру, которая создается в отдельном файле

Animal.swift

struct animalStruct { 
    static let path = NSBundle.mainBundle().pathForResource("animal", ofType: "JSON") 

    static let jsonData = NSData(contentsOfFile:path!, options: .DataReadingMappedIfSafe, error: nil) 

    static var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary 
} 

И это называется в контроллер табличного с помощью следующей

AnimalTableViewController

var array : NSArray = Animal.animalStruct.jsonResult["animal"] as NSArray 

код, используемый для поиска:

AnimalTableViewController

@IBOutlet var segmentedSortOption: UISegmentedControl! 
    var array : NSArray = Animal.pokemonStruct.jsonResult["animal"] as NSArray 
    var filteredAnimal = [String]() 
    var resultSearchController = UISearchController() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.resultSearchController = ({ 
      let controller = UISearchController(searchResultsController: nil) 
      controller.searchResultsUpdater = self 
      controller.dimsBackgroundDuringPresentation = false 
      controller.searchBar.sizeToFit() 

      self.tableView.tableHeaderView = controller.searchBar 

      return controller 
     })() 
     self.tableView.reloadData() 
    } 

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     if tableView == self.searchDisplayController?.searchResultsTableView { 
     return self.filteredAnimal.count 
     } else { 
      return self.array.count 
     } 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     var myCell:cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as cell 
     var upperCasedNames = array[indexPath.row]["name"] as? String 
     var searchedItem:String 

     if segmentedSortOption.selectedSegmentIndex == 0 { 
      if (self.resultSearchController.active) { 
       //**ISSUE OCCURS HERE** 
       myCell.name.text = filteredAnimal[indexPath.row] 
       return myCell 
      } 
      else { 
       myCell.name.text = upperCasedNames?.uppercaseString 
       return myCell 
      } 
     } else if segmentedSortOption.selectedSegmentIndex == 1 { 

      if let unsortedEvents = Animal.animalStruct.jsonResult["animal"] as? NSArray { 
       let descriptor = NSSortDescriptor(key: "name", ascending: true, selector: "caseInsensitiveCompare:") 
       let aToZ = unsortedEvents.sortedArrayUsingDescriptors([descriptor]) 
       upperCasedNames = aToZ[indexPath.row]["name"] as? String 
       myCell.name.text = upperCasedNames?.uppercaseString 
      } 
     } 
     return myCell 
    } 

    func updateSearchResultsForSearchController(searchController: UISearchController) 
    { 
     filteredAnimal.removeAll(keepCapacity: false) 
     let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text) 
     let arrays = (array).filteredArrayUsingPredicate(searchPredicate!) 
     filteredArray = arrays as [[String]] 
     self.tableView.reloadData() 
    } 
} 

Мой вопрос

Проблема у меня в том, что, когда я пытаюсь искать через UISearchBar, в тот момент я нажимаю на него, я получаю «фатальную ошибку: массив не может быть устранен от Objective-C ». Я считаю, что это происходит потому, что массивы, используемые в учебнике, отличаются от тех, которые я использовал.

ОБНОВЛЕНИЕ

Во-первых, основной проблемой было то, что тот факт, у меня был другой тип массива по сравнению с обучающей; поэтому я изменил var filteredAnimal = [String]() на var filteredArray = [[String:AnyObject]](), поскольку файл источника данных/JSON имел множество массивов данных. И обработайте его как AnyObject из-за этого, что позволило мне вызвать конкретную информацию из файла JSON.

Причины, почему я вернулся с пустым массивом была, потому что я не назначал искомые значения в пустом массиве в рамках метода updateSearchResultsController, поэтому я добавил следующую только перед загрузкой данных таблицы - filteredArray = arrays as [[String:AnyObject]]

Это все еще не решило проблему, поскольку мне пришлось изменить оператор if в пределах numberOfRowsInSection от tableView == self.searchDisplayController?.searchResultsTableView до self.resultSearchController.active, который затем получил реальный результат.

Однако сам поиск по-прежнему не работает, но большинство проблем было разрешено. При нажатии на панель поиска он извлекает только конечный индекс массива, и при поиске чего-либо он удаляет значение. Я продолжу работать над этим и, надеюсь, вскоре разрешу этот вопрос. Спасибо за помощь до сих пор!

+0

Что вы хотите сказать? – Moritz

+0

@ EricD. Извинения, добавили его сейчас – Javz

+0

Невозможно понять, какова ваша проблема, не видя кода UISearchBar. Пожалуйста, опубликуйте это. – mattt

ответ

0

С момента последнего обновления (который играет важную роль для решения) все, что я сделал, было изменить запрос NSPredicate из SELF CONTAINS[c] %@ - name CONTAINS[c] %@, и теперь при поиске он отображает правильный объект соответствия на основе его имени.

0

Ниже ссылка может помочь вам решить вашу проблему:

How can I fix "fatal error: can't index empty buffer"

in your code 

let arrays = (array).filteredArrayUsingPredicate(searchPredicate!) 

will create new reference of arrays. 
+0

Я сделал println, когда поиск активируется, массив пуст - вы бы поняли почему? Я следил за учебником, так как это минус источник данных. Что касается вашего решения, есть строка кода, которая уже очевидна: 'filterAnimal.removeAll (keepCapacity: false)' Спасибо! – Javz

Смежные вопросы