【问题标题】:trying to use the "search" method but I still have an error尝试使用“搜索”方法,但我仍然有错误
【发布时间】:2018-12-23 01:04:04
【问题描述】:

您好,这是我第一次尝试使用搜索方法,我正在使用 Apple Developer 网站上的搜索栏指南,但我遇到了这个问题,似乎无法弄清楚。我将数据存储在 Class DataServices 中,并且我的 tableView 单元格在我的 ViewController 中工作得非常完美,但我似乎无法弄清楚我应该在搜索方法中返回什么来完成该方法,当我这样做时就像搜索指南指令 Xcode 对我尖叫一样。你能用你的知识祝福我吗

class ListVC: UIViewController,UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {

    @IBOutlet weak var searchBar: UISearchBar!

    @IBOutlet weak var tableView: UITableView!

    var filteredData: [List]!
    let data = DataServices.instance.getList()

    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
        tableView.dataSource = self
        tableView.dataSource = self
        filteredData = data
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return DataServices.instance.getList().count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "ListingCell") as? ListCell {
            let listing = DataServices.instance.getList()[indexPath.row]
            cell.updateView(lists: listing)
            return cell
        }else {
            return ListCell()
        }
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        filteredData = searchText.isEmpty ? data: data.filter({ (List: String) -> Bool in
            return List.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil    

> Value of type 'List' has no member 'range' is the error I get

        })

        tableView.reloadData()
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        self.searchBar.showsCancelButton = true
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.showsCancelButton = false
        searchBar.text = ""
        searchBar.resignFirstResponder()

    }

}

类数据服务 { static let instance = DataServices()

private let currentList = [
    List(firstText: "Name", secondText: "Shannon"),
    List(firstText: "Car", secondText: "Infinity"),
    List(firstText: "City", secondText: "Brandon"),
    List(firstText: "Wife", secondText: "Naedra"),
    List(firstText: "Child", secondText: "Shantae"),
    List(firstText: "Job", secondText: "Driver"),
    List(firstText: "Cell", secondText: "iPhone"),
    List(firstText: "Computer", secondText: "Imac")

]

func getList() -> [List] {
return currentList
}

}

结构列表{

private (set) public var toptitle: String
private (set) public var bottomtitle: String

init(firstText: String, secondText: String) {
    self.toptitle = firstText
    self.bottomtitle = secondText
}

}

【问题讨论】:

  • 请编辑您的问题以显示List 的定义 - 您想要$0.someProperty 其中someProperty 是您要过滤的字符串属性。您现在拥有的代码正在尝试在 List 类上调用 range
  • 另外,DataServices.instance.getList() 是否执行网络操作?如果是这样,那么您不应该重复这样做 - 您应该获取一次数据
  • DataServices.instance.getList() 来自我存储数据的 swift 文件,这里是代码
  • 我添加了带有代码的文件以显示更多信息

标签: ios swift3 xcode8 swift4


【解决方案1】:

闭包参数代表实例而不是类型,并且应用于数组的filter 闭包只接受一个参数。检查空字符串是多余的。

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    filteredData = data.filter ({ (list) -> Bool in
        return list.firstText.range(of: searchText, options: .caseInsensitive) != nil ||
               list.secondText.range(of: searchText, options: .caseInsensitive) != nil
    })
    tableView.reloadData()
}

或使用简化语法

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    filteredData = data.filter { $0.firstText.range(of: searchText, options: .caseInsensitive) != nil ||
                                 $0.secondText.range(of: searchText, options: .caseInsensitive) != nil }  
    tableView.reloadData()
}

我建议将filteredData 声明为非可选的空数组以避免不必要的展开

var filteredData = [List]()

并强制向下转换单元格,如果代码崩溃则表明设计错误。

let cell = tableView.dequeueReusableCell(withIdentifier: "ListingCell", for: indexPath) as! ListCell

如果你想要 List 结构中的常量,只需编写

struct List {
    let toptitle: String
    let bottomtitle: String
}

您可以免费获得初始化程序。 private (set) var 非常objective-c-ish

最终在每次调用cellForRow 时获得相同的(静态)列表是不必要的昂贵,从data 获取项目

let listing = data[indexPath.row]

【讨论】:

  • 它仍然向我抛出一个错误,指出 List 类型的值没有成员 'range' func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { filteredData = data.filter({ ( string) -> Bool in return string.range(of: searchText, options: .caseInsensitive) != nil }) tableView.reloadData() }
  • 对不起,我的错,你必须检查字符串属性的范围。我更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 2020-06-21
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多