ios - 具有多个数据的 Swift 搜索栏

标签 ios swift swift3 tableview searchbar

我有 5 个标签,它们在 tableView 的每个单元格中接收来自 SQL 查询数组的数据。我想在上面实现搜索栏。搜索栏应搜索 1 个特定标签的数据。它正在工作并过滤该特定标签但是当它被过滤时,其他 4 个标签不会更新并且它们根本没有改变。我想不通。由于我只有 1 个来自搜索栏条目的过滤数据,所以我不知道应该如何过滤其他数据。 谢谢

编辑:仍然无法弄清楚类和添加数据,我有一个错误

"Value of type '[String]' has no member 'localizedCaseInsensitiveContains'"

关于搜索栏功能

import UIKit

class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {

var data:[MyData] = []
@IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered:[MyData] = []

@IBAction func sqlExecute(_ sender: AnyObject) {

var client = SQLClient()
    client.connect("sql_ip", username: "username", password: "password", database: "database") {
        success in

        if success {
            client.execute("sql query") {
                result in

                for table in result as Any as! NSArray {
                    for row in table as! NSArray {
                        for column in row as! NSDictionary {

                            if column.key as! String == "data1" {
                                MyData.init(data1: "\(column.value)")
                            } else if column.key as! String == "data2" {
                                MyData.init(data2: column.value as! Double)
                            } else if column.key as! String == "data3" {
                                MyData.init(data3: "\(column.value)")
                            } else if column.key as! String == "data4" {
                                MyData.init(data4: "\(column.value)")
                            } else if column.key as! String == "data5" {
                                MyData.init(data5: "\(column.value)")
                            }
                        }
                    }
                }
                client.disconnect()
                self.tableView.reloadData()
            }
        }
    }
}
override func viewDidLoad() {
    super.viewDidLoad()


    tableView.delegate = self
    tableView.dataSource = self
    searchBar.delegate = self
}

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


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

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


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "segue", for: indexPath)

    if(searchActive) {

        cell.label1.text = "\(filtered[indexPath.row])"
        cell.label2.text = "\(filtered[indexPath.row])"
        cell.label3.text = "\(filtered[indexPath.row])"
        cell.label4.text = "\(filtered[indexPath.row])"
        cell.label5.text = "\(filtered[indexPath.row])"
    } else {

    cell.label1.text = "\(data[indexPath.row])"
    cell.label2.text = "\(data[indexPath.row])"
    cell.label3.text = "\(data[indexPath.row])"
    cell.label4.text = "\(data[indexPath.row])"
    cell.label5.text = "\(data[indexPath.row])"
    }
    cell.backgroundColor = UIColor.clear
    cell.selectionStyle = UITableViewCellSelectionStyle.none
    return cell
}


func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    searchActive = true;
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
    if(filtered.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.tableView.reloadData()
}

这是类文件:

import Foundation

class MyData {
var data1 = [String]()
var data2 = [Double]()
var data3 = [String]()
var data4 = [String]()
var data5 = [String]()


init(data1: String) {
    self.data1.append(data1)
}
init(data2: Double) {
    self.data2.append(data2)
}
init(data3: String) {
    self.data3.append(data3)
}
init(data4: String) {
    self.data4.append(data4)
}
init(data5: String) {
    self.data5.append(data5)
}
}

最佳答案

你的问题是你有五个不同的数组,而不是你需要一个类型为 Dictionary 或者自定义 Struct/class 的数组.如果你像这样使用 struct/class 就更好了。

class MyData {
    var data1: String!
    var data2: Double!
    var data3: String!
    var data4: String!
    var data5: String! 

    init(data1: String, data2: Double, data3: String, data4: String, data5: String) {
         self.data1 = data1
         self.data2 = data2
         self.data3 = data3
         self.data4 = data4
         self.data5 = data5
    }
}

现在不再有五个不同的数组,一个用于过滤器,而是创建两个 [MyData] 类型的 Array,其中一个用于显示 filterData 并将其与 tableView 方法并像这样过滤它。

使用 init 方法创建 MyData 的对象并将其附加到数据数组,然后像这样在 searchBar 委托(delegate)中过滤。

filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }

上面的过滤器将在数据数组中搜索并返回属性 data1 包含 searchText 的所有对象。

你的整个代码应该是这样的

import UIKit

class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {

    var data:[MyData] = []

    @IBOutlet weak var searchBar: UISearchBar!
    var searchActive : Bool = false
    var filtered:[MyData] = []


    override func viewDidLoad() {
        super.viewDidLoad()


        tableView.delegate = self
        tableView.dataSource = self
        searchBar.delegate = self
    }

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


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

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


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "segue", for: indexPath)

        if(searchActive) {

            cell.label1.text = filtered[indexPath.row].data1
            cell.label2.text = filtered[indexPath.row].data2
            cell.label3.text = filtered[indexPath.row].data3
            cell.label4.text = "\(filtered[indexPath.row].data4) ₺"
            cell.label5.text = filtered[indexPath.row].data5
        } else {

            cell.label1.text = data[indexPath.row].data1
            cell.label2.text = data[indexPath.row].data2
            cell.label3.text = data[indexPath.row].data3
            cell.label4.text = "\(data[indexPath.row].data4) ₺"
            cell.label5.text = data[indexPath.row].data5
        }
        cell.backgroundColor = UIColor.clear
        cell.selectionStyle = UITableViewCellSelectionStyle.none
        return cell
    }


    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        searchActive = true;
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        searchActive = false;
        self.searchBar.endEditing(true)
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchActive = false;
        self.searchBar.endEditing(true)
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchActive = false;
        self.searchBar.endEditing(true)
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
        if(filtered.count == 0){
            searchActive = false;
        } else {
            searchActive = true;
        }
        self.tableView.reloadData()
    }
}

编辑:您需要像这样使用单个数组。

for table in result as Any as! NSArray {
    for row in table as! NSArray {
        if let dic = row as? [String : Any] {
            let data1 = dic["data1"] as! String
            let data2 = dic["data2"] as! Double
            let data3 = dic["data3"] as! String
            let data4 = dic["data4"] as! String
            let data5 = dic["data5"] as! String
            let newData =  MyData(data1: data1, data2: data2, data3: data3, data4: data4, data5: data5)
            self.data.append(newData)
        }
    }
}
self.tableView.reloadData()

关于ios - 具有多个数据的 Swift 搜索栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40716026/

相关文章:

swift - SKLabelNode 相关 EXC_BAD_ACCESS 崩溃

ios - 字典有可选键

iphone - 增加/减少 UIImageView 的亮度

Swift Combine sink 值与@Published 属性的值不同

swift - 如何在 Swift 中创建带有边框和阴影的圆形图像作为 MKAnnotationView?

具有值类型的 JSONSerialization

swift - 如何在NSView中实现放大镜

ios - 如何只显示网页的一部分? UIWebView Swift

ios - OAuth2 与雅虎 API

ios - 文件所有者中没有显示导出或操作