在 tableview 的文本字段中搜索

Posted

技术标签:

【中文标题】在 tableview 的文本字段中搜索【英文标题】:searching in the textfield of the tableview 【发布时间】:2018-04-30 05:58:02 【问题描述】:

tableViewtextField 中搜索。

我需要从tableView 中搜索名称。所以为此我在UIViewController 中有tableViewtextField

我需要从 Api 搜索。为此,我使用了 Alamofire 方法来获取数据。

我需要搜索。现在我实现将名称从 api 显示到 tableView 我得到了输出。但我需要在mvvm 中实现搜索.how to do。

我的模型:-

class SearchModel: NSObject 
    var restaurantname :String!
    init?(dictionary :JSONDictionary) 

        guard let name = dictionary["name"] as? String  else 
                return
        
        self.restaurantname = name
    

我的视图模型:-

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 

        @IBOutlet private weak var tableView: UITableView!

        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")
        

        override func viewDidLoad() 
            super.viewDidLoad()

           //  tableView.dataSource = self
           //  filteredData = data

            searchViewModel.loadData  (isSuccess) in
            if(isSuccess == true) 
                self.tableView .reloadData()
            
            else 
            
            
          //  self.tableView .reloadData()
          // Do any additional setup after loading the view.
        

        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))
           //   cell.name.text = searchViewModel.datafordisplay(atindex: indexPath)
           //  cell.name.text = filteredData[indexPath.row]

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

           return cell
        

       /*
         // MARK: - Navigation

         // In a storyboard-based application, you will often want to do a little preparation before navigation
         override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
         // Get the new view controller using segue.destinationViewController.
         // Pass the selected object to the new view controller.
         
         */

    

tableViewCell:-

class SearchCell: UITableViewCell 
   @IBOutlet weak var name: UILabel!

    override func awakeFromNib() 
        super.awakeFromNib()
    

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


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

这是我的代码。现在如何在这里实现搜索。

【问题讨论】:

有没有人能解决这个问题。 @kuldeep 你能解决这个问题吗?怎么办 你通过下面的链接了吗..dev.to/eleazar0425/mvvm-pattern-sample-in-swiftios--58aj @Bharath 这个链接没问题...但我不明白如何在代码中实现 【参考方案1】:

没有办法搜索。

    当您输入文本并按下搜索按钮时。 当您键入时,不使用 搜索按钮 进行搜索。

1的解决方案:

你需要在搜索按钮上调用一个方法

搜索按钮。

func Search() 
        predicate = NSPredicate(format: "Self.YourSearchListName beginsWith[c]%@", SearchName)
        GetsearchList = YourArrayForSearch.filtered(using: predicate) as NSArray

        YourTable.reloadData()
    

第二个解决方案

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
 if textField == self.YourTextFieldName
    Search()

    

对于第二个解决方案,不要忘记设置委托。

【讨论】:

但我需要在 mvvm 中做 @emmamichael 我已经提供了逻辑。您需要根据您的要求在项目中实施。【参考方案2】:

filteredContactListArray 是保存过滤数据的数组,用于在用户开始搜索特定文本时重新加载 tableview。

@IBOutlet var searchCityTextField: UITextField!
var filteredSearchArray :SearchViewModel!

在 Viewdidload() 函数中

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

UItextfieldDelegate 方法

func textFieldDidChange(textField: UITextField) 
        if textField.text == "" 
            filteredSearchArray = searchViewModel// contactListArray is the actual array with all the list of data.
            citiesTableView.reloadData()
        else
            filterContentForSearchText(textField.text!)
        


func filterContentForSearchText(searchText: String) 
        filteredSearchArray = NSMutableArray(array:searchViewModel. dataListArray.filter((ele:AnyObject) -> Bool in
            return (ele as! searchViewModel).cityName.lowercased().contains(searchText.lowercased())
        ))
        citiesTableView.reloadData()

UItableviewDelegate 方法

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return filteredContactListArray.count

【讨论】:

这里我的所有数据都存储在 searchViewModel.datasourceModel.dataListArray 并且它是 Array 的格式所以,这里显示为错误。错误是无法分配 Array? totype NSMutableArray.那么怎么解决 在此返回 (ele as!QM_SearchModel).restaurantname.lowercaseString.containsString(searchText.lowercaseString) 此处显示错误,因为字符串类型的值没有成员 'containString'。所以这里如何解决 而且我也必须在 mvvm 中实现,所以如何在 viewmodel 中实现 我更新了我的答案,你可以再试一次,因为我没有测试过 @Vinaykrishnan 仍然有问题。因为我已经在问题中上传了我的代码。所以来自 api 的数据存储在 SearchViewModel 的 datasourceModel 中。在该数据中我有名称。所以我需要根据那。那么如何在该方法中执行。根据您的回答,它在句子上显示错误:- txt.addTarget(self, action: #selector(SearchViewController.textFieldDidChange(_:)), for: UIControlEvents.EditingChanged) 这里它在这里显示为没有成员'textfieldchanged.AND在函数中:-func textFieldDidChange(textField:UITextField)这里显示为私有。那么如何解决

以上是关于在 tableview 的文本字段中搜索的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa - 如何为 tableView 创建搜索字段?

在 tableView 中获取 TextField 标识

iOS中tableview中的动态搜索

Table View 窗外屏幕 iOS Objective C

TableView 刷新和文本字段

在 Tableview 中创建搜索字段