使用mvvm搜索tableview

时间:2018-05-03 04:05:29

标签: ios iphone swift swift3

我需要在tableview中搜索。我有tableview和textfield.While点击文本字段,它必须搜索tableview。

我的模特: -

     class SearchModel: NSObject {


 var restaurantname :String!


    init?(dictionary :JSONDictionary) {

        guard let name = dictionary["name"] as? String  else {
                return
        }

        self.restaurantname = name

    }



}

我的viewmodel: -

class SearchViewModel: NSObject {


    var datasourceModel:SearchDataSourceModel

    init(withdatasource  newDatasourceModel: SearchDataSourceModel) {
        datasourceModel = newDatasourceModel
    }


    func datafordisplay(atindex indexPath: IndexPath) -> SearchModel{
        return  datasourceModel.dataListArray![indexPath.row]

    }

    func numberOfRowsInSection(section:Int) -> Int {

        return (datasourceModel.dataListArray?.count)!
    }




    func loadData(completion :@escaping (_ isSucess:Bool) -> ()){


        loadFromWebserviceData { (newDataSourceModel) in

            if(newDataSourceModel != nil)
            {




                self.datasourceModel = newDataSourceModel!
                completion(true)

            }
            else{
                completion(false)
            }
        }
    }


    //}
    func loadFromWebserviceData(completion :@escaping (SearchDataSourceModel?) -> ()){

        //with using Alamofire  ..............

        Alamofire.request("http://www.example.com").validate(statusCode: 200..<300).validate(contentType: ["application/json"]).responseJSON{ response in


            switch response.result{

            case .success(let data):
                print("success",data)


                let result = response.result
                if     let wholedata = result.value as? [String:Any]{


                    if  let data = wholedata["data"] as? Array<[String:Any]>{
                        //  print(data["name"] as! String)
                        print(data)
                        print(response)
                        let newDataSource:SearchDataSourceModel = SearchDataSourceModel(array: data)

                        completion(newDataSource)
                        //       }
                    }
                }
                //  case .failure(let data):
                //  print("fail",data)


            case .failure(let encodingError ):
                print(encodingError)


                //  if response.response?.statusCode == 404{


                print(encodingError.localizedDescription)

                completion(nil)

                //   }
            }




        }}
}

我的数据源模型: -

class SearchDataSourceModel: NSObject {



    var dataListArray:Array<SearchModel>? = []




    init(array :Array<[String:Any]>?) {
        super.init()
        var newArray:Array<[String:Any]> = []
        if array == nil{

         //   newArray = self.getJsonDataStored44()
        }
        else{
            newArray = array!

        }

        var datalist:Array<SearchModel> = []
        for dict in newArray{

            let model = SearchModel(dictionary: dict)

            datalist.append(model!)
        }
        self.dataListArray = datalist


          }



}

我的viewcontroller: -

class SearchViewController: UIViewController,UITableViewDelegate,UITableViewDataSource, UISearchBarDelegate,UITextFieldDelegate {


    @IBOutlet private weak var tableView: UITableView!
  !
    @IBOutlet weak var txt: UITextField!

    var filteredSearchArray = NSMutableArray()



    private var searchViewModel :SearchViewModel!

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, withViewModel viewModel:SearchViewModel) {

        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        searchViewModel  = viewModel
    }



    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }



    var filteredData: [String]!



    override func viewDidLoad() {
        super.viewDidLoad()




        txt.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)



        searchViewModel.loadData { (isSuccess) in


            if(isSuccess == true)
            {


                self.tableView .reloadData()


            }
            else{


                }
        }



    }


    @objc private func textFieldDidChange(textField: UITextField) {
        if textField.text == "" {
           self .viewDidLoad()
        }else{
            filterContentForSearchText(searchText: textField.text!)
        }
    }



    func filterContentForSearchText(searchText: String) {
        filteredSearchArray = NSMutableArray(array:(searchViewModel.datasourceModel.dataListArray?.filter({(ele:AnyObject) -> Bool in
            return (ele as! SearchModel).restaurantname.lowercased().contains(searchText.lowercased())
        }))!)
        tableView.reloadData()
    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchViewModel.numberOfRowsInSection(section: section)
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let identifier = "searchcell"
        var cell: SearchCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? SearchCell

        if cell == nil {
            tableView.register(UINib(nibName: "SearchCell", bundle: nil), forCellReuseIdentifier: identifier)
            cell = tableView.dequeueReusableCell(withIdentifier: identifier) as?SearchCell
        }


   cell.setsearchData(search: searchViewModel.datafordisplay(atindex: indexPath))



        return cell
    }


}

我的tableviewcell: -

class SearchCell: UITableViewCell {




  @IBOutlet weak var name: UILabel!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }


    func setsearchData(search:SearchModel)
    {
        self.name.text = search.restaurantname


    }
}

这是我的代码,但在filteredSearchArray中始终显示为0元素。

此处显示名称列表,但单击未搜索且未重新加载的文本字段。如何解决问题。

此代码中没有数据: -

 func filterContentForSearchText(searchText: String) {
        filteredSearchArray = NSMutableArray(array:(searchViewModel.datasourceModel.dataListArray?.filter({(ele:AnyObject) -> Bool in
            return (ele as! SearchModel).restaurantname.lowercased().contains(searchText.lowercased())
        }))!)
        tableView.reloadData()
    }

1 个答案:

答案 0 :(得分:0)

首先,一件重要的事情不要在NSArray使用NSDictionaryswift而使用ArrayDictionary

我在你的模型类中进行了更改:

class SearchModel: NSObject {
    var restaurantname :String!
    init(dictionary :JSONDictionary) {
        self.restaurantname = dictionary["name"] as? String ?? ""
    }
}

现在过滤你的数组:

filteredSearchArray = searchViewModel.datasourceModel.dataListArray?.filter {$0.restaurantname.lowercased().contains(searchText.lowercased())}

现在在filteredSearchArray数据源中传递tableView,然后重新加载表格。您可以使用bool变量isSearching来检查您必须在数据源中传递哪个数组,过滤后的原始数据。在isSearchingtextFieldDidBeginEiditng方法中切换textFieldDidEndEiditng

我在我的操场上通过以下示例对其进行了测试:

var models: Array<SearchModel> = [SearchModel.init(dictionary: ["name": "Khalsa Dhaba"]), SearchModel.init(dictionary: ["name": "Yo! China"]), SearchModel.init(dictionary: ["name": "Sher-e-punjab"]), SearchModel.init(dictionary: ["name": "Haveli"])]
let result = models.filter {$0.restaurantname.lowercased().contains("o!".lowercased())}
print(result)

工作正常! 其次,我注意到你正在通过调用self.viewDidLoad()方法来重新加载你的视图,你不应该调用它来调用它本身,它是viewContoller生命周期的函数。请改为呼叫tableView.reloadData()