我正在使用自动填充功能在搜索栏上工作。有时在自动填充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})'
如果我对此行发表评论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
}
}
答案 0 :(得分: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
}
}