Swift Searchbar 应用程序在筛选 2 个数组时崩溃
Swift Searchbar App crashing while filtering 2 arrays
我正在用两个数组填充一个表视图。在应用程序崩溃的搜索栏中输入两个字符后,我一直收到错误消息,因为数组计数不相同。我已经对此进行了一段时间的试验,但我无法找到解决方案。与此类似的帖子有 2 个数组,但对于每个 'set',我有一个包含数据(数据和 PostUser)的数组,以及一个包含相同数据但已过滤(filteredData 和 PostUserFiltered)的数组。我不能将他们的解决方案应用于我的。
import UIKit
import Firebase
class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var data:[String] = []
var filteredData: [String] = [String]()
var idArray:[String] = []
var postUser:[String] = []
var postUserFiltered: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
let ourId = UserDefaults.standard.object(forKey: "SearchIds")
print("Our ids\(ourId!)")
self.idArray = ourId! as! [String]
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.data.append(test)
print(test)
self.filteredData = self.data
print("data: \(self.filteredData)")
self.tableView.reloadData()
}
})
}
self.filteredData = self.data
///////////////////////////////////////////////////////////////
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.postUser.append(test)
print(test)
self.postUserFiltered = self.postUser
print("data: \(self.postUserFiltered)")
self.tableView.reloadData()
}
})
}
self.postUserFiltered = self.postUser
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = self.filteredData[indexPath.row]
cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postUserFiltered.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
////////////////for the username now
postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
self.tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
错误是因为您的 2 个数组的长度不匹配,即 filteredData 和 postUserFiltered。
原因是您过滤过滤数据的依据是它是否包含在搜索字段中输入的文本。仅过滤 post 用户并获取他的相应 post 而删除其他用户。
我建议您使用字典而不是 2 个不同的数组,其中键是 postUser,值是数据。
您可以根据键过滤字典,从而保留 post用户与正确数据的对应关系
如果你还想使用2个数组,你可以使用下面的代码;我已经为你修改了你的代码。
import UIKit
import Firebase
class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var data:[String] = []
var filteredData: [String] = []
var idArray:[String] = []
var postUser:[String] = []
var postUserFiltered: [String] = []
var mapping: [String:Int] = [:]
override func viewDidLoad() {
super.viewDidLoad()
let ourId = UserDefaults.standard.object(forKey: "SearchIds")
print("Our ids\(ourId!)")
self.idArray = ourId! as! [String]
var index = 0;
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.data.append(test)
print(test)
self.filteredData = self.data
print("data: \(self.filteredData)")
self.tableView.reloadData()
}
})
}
self.filteredData = self.data
///////////////////////////////////////////////////////////////
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.postUser.append(test)
print(test)
self.mapping[test] = index;
self.postUserFiltered = self.postUser
print("data: \(self.postUserFiltered)")
self.tableView.reloadData()
}
})
index += 1;
}
self.postUserFiltered = self.postUser
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = self.data[self.mapping[self.postUserFiltered[indexPath.row]]]
cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let postUserFiltered = self.postUserFiltered{
return postUserFiltered.count
}
return 0
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
////////////////for the username now
postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
self.tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我正在用两个数组填充一个表视图。在应用程序崩溃的搜索栏中输入两个字符后,我一直收到错误消息,因为数组计数不相同。我已经对此进行了一段时间的试验,但我无法找到解决方案。与此类似的帖子有 2 个数组,但对于每个 'set',我有一个包含数据(数据和 PostUser)的数组,以及一个包含相同数据但已过滤(filteredData 和 PostUserFiltered)的数组。我不能将他们的解决方案应用于我的。
import UIKit
import Firebase
class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var data:[String] = []
var filteredData: [String] = [String]()
var idArray:[String] = []
var postUser:[String] = []
var postUserFiltered: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
let ourId = UserDefaults.standard.object(forKey: "SearchIds")
print("Our ids\(ourId!)")
self.idArray = ourId! as! [String]
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.data.append(test)
print(test)
self.filteredData = self.data
print("data: \(self.filteredData)")
self.tableView.reloadData()
}
})
}
self.filteredData = self.data
///////////////////////////////////////////////////////////////
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.postUser.append(test)
print(test)
self.postUserFiltered = self.postUser
print("data: \(self.postUserFiltered)")
self.tableView.reloadData()
}
})
}
self.postUserFiltered = self.postUser
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = self.filteredData[indexPath.row]
cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postUserFiltered.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
////////////////for the username now
postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
self.tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
错误是因为您的 2 个数组的长度不匹配,即 filteredData 和 postUserFiltered。
原因是您过滤过滤数据的依据是它是否包含在搜索字段中输入的文本。仅过滤 post 用户并获取他的相应 post 而删除其他用户。
我建议您使用字典而不是 2 个不同的数组,其中键是 postUser,值是数据。
您可以根据键过滤字典,从而保留 post用户与正确数据的对应关系
如果你还想使用2个数组,你可以使用下面的代码;我已经为你修改了你的代码。
import UIKit
import Firebase
class SearchPostsController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var data:[String] = []
var filteredData: [String] = []
var idArray:[String] = []
var postUser:[String] = []
var postUserFiltered: [String] = []
var mapping: [String:Int] = [:]
override func viewDidLoad() {
super.viewDidLoad()
let ourId = UserDefaults.standard.object(forKey: "SearchIds")
print("Our ids\(ourId!)")
self.idArray = ourId! as! [String]
var index = 0;
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/message").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.data.append(test)
print(test)
self.filteredData = self.data
print("data: \(self.filteredData)")
self.tableView.reloadData()
}
})
}
self.filteredData = self.data
///////////////////////////////////////////////////////////////
for singleId in idArray {
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(singleId)/username").observe(.value, with: { (snapshot) in
if let test = snapshot.value as? String!{
self.postUser.append(test)
print(test)
self.mapping[test] = index;
self.postUserFiltered = self.postUser
print("data: \(self.postUserFiltered)")
self.tableView.reloadData()
}
})
index += 1;
}
self.postUserFiltered = self.postUser
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = self.data[self.mapping[self.postUserFiltered[indexPath.row]]]
cell.detailTextLabel?.text = self.postUserFiltered[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let postUserFiltered = self.postUserFiltered{
return postUserFiltered.count
}
return 0
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
////////////////for the username now
postUserFiltered = searchText.isEmpty ? postUser : postUser.filter { (item: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
self.tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}