2017-01-11 2 views
1

Я работаю над панелью поиска с функцией автозаполнения. Иногда я получаю эту ошибку при касании клетки в автозаполнения TableView:Исключение запроса на ошибку при недействительном указателе пути на ячеистой машине

*** неудача Assertion в - [UITableViewRowData rectForRow: надрез: heightCanBeGuessed:], /BuildRoot/Library/Caches/com.apple.xbs/Sources /UIKit_Sim/UIKit-3505.16/UITableViewRowData.m:1849

*** Нагрузочного приложение из-за неперехваченное исключение 'NSInternalInconsistencyException', причина: «запрос для прямоугольника на недопустимом пути индекса ({длина = 2, путь = 0 - 3}) '

Если я прокомментирую эту строку, то searchBar.text = cell.textLabel!.text приложение не разбивается.

Вот полный код функции:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     let cell: UITableViewCell = tableView.cellForRow(at: indexPath)! 
     address = cell.textLabel!.text! 
     searchBar.text = cell.textLabel!.text 
    } 

Как я могу это исправить?

UPD: Похоже, он выходит из строя после того, как searchBar.text = cell.textLabel!.text
Я добавил print(searchBar.text!) и печатает правильное значение утешать

UPD2: App падает только если я что-то типа в строке поиска, а затем нажмите где-нибудь на экране, чтобы закрыть клавиатуру, а затем нажмите на одну из автозаполняющих ячеек.

Код класса:

import UIKit 
import Alamofire 
import SwiftyJSON 

class StreetSelectViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UINavigationControllerDelegate 
{ 
    var data: [String] = ["Нет данных"] 
    var filtered: [String] = [] 
    var searchActive : Bool = false 

    @IBOutlet weak var cityNameLabel: UILabel! 
    @IBOutlet weak var searchBar: UISearchBar! 
    @IBOutlet weak var tableView: UITableView! 
    @IBOutlet weak var topSpaceConstraint: NSLayoutConstraint! 
    @IBOutlet var gradientBackground: GradientView! 

    let segueIdentifier = "ShowStreetSelectSegue" 

    //background gradient 
    override func viewDidLayoutSubviews() 
    { 
     self.gradientBackground.create() 
    } 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     //side menu panGestureRecognizer 
     if self.revealViewController() != nil 
     { 
      self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) 
     } 

     tableView.delegate = self 
     tableView.dataSource = self 
     searchBar.delegate = self 
     tableView.tableFooterView = UIView() 
     navigationController?.delegate = self 

     //search bar settings 
     let barImage = UIImage() 
     searchBar.setBackgroundImage(barImage, for: .any, barMetrics: .default) 
     searchBar.scopeBarBackgroundImage = barImage 
     searchBar.tintColor = UIColor.lightGray 
     searchBar.setValue("Отмена", forKey:"_cancelButtonText") 
     searchBar.showsCancelButton = false 

     topSpaceConstraint.constant = self.navigationController!.navigationBar.frame.height + 8 

     //network 
     let queue = DispatchQueue(label: "com.admin.response-queue", qos: .utility, attributes: [.concurrent]) 
     URLCache.shared.removeAllCachedResponses() 
     Alamofire.request("").validate() 
      .responseJSON(
       queue: queue, 
       completionHandler: { response in 
        if let JSON = response.result.value 
        { 
         self.data.removeAll() 
         let json = SwiftyJSON.JSON(JSON) 
         print("JSON: \(json)") 
         for (_, object) in json 
         { 
          self.data.append(object.stringValue) 
          print(self.data) 
         } 
        } 
        DispatchQueue.main.async { 
         self.tableView.reloadData() 
        } 
      } 
     ) 
    } 

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

    override func viewWillAppear(_ animated: Bool) 
    { 
     cityNameLabel.text = cityName 
    } 

    //MARK: - search bar settings 
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) 
    { 
     searchActive = true; 
     self.navigationController?.isNavigationBarHidden = true 
     topSpaceConstraint.constant = 8 
    } 

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 
    { 
     searchActive = false; 
     self.navigationController?.isNavigationBarHidden = false 
    } 

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) 
    { 
     searchActive = false; 
     filtered = data 
     tableView.isHidden = false 
     tableView.reloadData() 
     topSpaceConstraint.constant = 8 
    } 

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
    {  
     if !searchActive 
     { 
      searchActive = true 
      tableView.reloadData() 
     } 

     self.searchBar.resignFirstResponder() 
     address = searchBar.text! 
     performSegue(withIdentifier: "ShowSearchResultsSeque", sender: Any?.self) 
    } 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
    { 
     filtered = data.filter({ (text) -> Bool in 
      let tmp: NSString = text as NSString 
      let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive) 
      return range.location != NSNotFound 
     }) 
     if(filtered.count == 0) 
     { 
      searchActive = false; 
     } 
     else 
     { 
      searchActive = true; 
     } 

     if searchText.characters.count != 0 
     { 
      tableView.isHidden = true 
     } 
     else 
     { 
      tableView.isHidden = false 
     } 

     tableView.reloadData() 
     topSpaceConstraint.constant = 8 
    } 

    //MARK: - tableview settings 

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     if searchActive 
     { 
      if filtered.count == 0 
      { 
       return data.count 
      } 
      else 
      { 
       return filtered.count 
      } 
     } 
     else 
     { 
      return data.count 
     } 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
     if searchActive 
     { 
      if filtered.count == 0 
      { 
       cell.textLabel?.text = data.sorted()[indexPath.row] 
      } 
      else 
      { 
       cell.textLabel?.text = filtered.sorted()[indexPath.row] 
      } 
     } 
     else 
     { 
      cell.textLabel?.text = data.sorted()[indexPath.row] 
     } 
     return cell 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     let cell: UITableViewCell = self.tableView.cellForRow(at: indexPath)! 
     address = cell.textLabel!.text! 
     self.searchBar.text = cell.textLabel!.text 
     print(searchBar.text!)   
    } 

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    { 
     cell.backgroundColor = UIColor.clear 
     //text color 
     cell.textLabel!.textColor = UIColor.white; 
     //cell selection color 
     let bgColorView = UIView() 
     bgColorView.backgroundColor = UIColor.black.withAlphaComponent(0.3) 
     cell.selectedBackgroundView = bgColorView 
     tableView.backgroundColor = UIColor.clear 
    }     
} 
+1

Вам нужно использовать массив, который вы использовали для установки текста 'textLabel' ячейки –

+0

Я пробовал, все еще падает – BadCodeDeveloper

+0

Проверьте, что ваша поисковая панель' Outlet' подключена к вашему viewController –

ответ

0

Я не уверен, почему, но проблема была в SearchDisplayController. После удаления его в раскадровке все работает отлично

1

Почему вы используете self.tableView.cellForRow в didSelectRowAt метод, вы можете использовать фильтрованную источник данных в didSelectRowAt метод, который вы уже использовали в cellForRowAt методе. вы можете выполнить следующие действия для достижения своей функциональности.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     if searchActive 
     { 
      if filtered.count == 0 
      { 
       address = data.sorted()[indexPath.row] 
      } 
      else 
      { 
       address = filtered.sorted()[indexPath.row] 
      } 
      self.searchBar.text = address 
     }   
    } 
+0

Приложение больше не работает, но автозаполнение работает только при отображении клавиатуры. Когда клавиатура скрывается, приложение не реагирует на ответные сообщения. В чем проблема? – BadCodeDeveloper

+0

Попробуйте еще одну вещь, удалите флажок 'searchActive' boolean и проверьте, присваивает ли ваш' filter.count> 0' значение только 'address' и' self.searchBar' –

+0

сбой с той же ошибкой, что и раньше :( – BadCodeDeveloper

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