2

我正在研究具有自动填充功能的搜索栏。有时在自动填充中点击单元格时会出现此错误TableView

*** -[UITableViewRowData rectForRow:inSection:heightCanBeGuessed:] 中的断言失败,/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UITableViewRowData.m:1849

*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“在无效索引路径 ({length = 2, path = 0 - 3}) 处请求 rect”

如果我评论这条线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:仅当我在搜索栏中输入内容,然后点击屏幕上的某个位置以关闭键盘,然后点击自动填充单元格之一时,应用程序才会崩溃。

班级代码:

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
    }                 
}
4

2 回答 2

1

为什么要self.tableView.cellForRowdidSelectRowAt方法中使用,您可以在方法中使用已过滤的数据源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
        }         
    }
于 2017-01-12T05:18:49.543 回答
0

我不知道为什么,但问题出在SearchDisplayController. 在情节提要中删除它后一切正常

于 2017-05-05T08:49:11.137 回答