【问题标题】:Search bar at the top of a UIPickerView in SwiftSwift 中 UIPickerView 顶部的搜索栏
【发布时间】:2015-05-18 07:15:32
【问题描述】:

所以我有一个 textField,当用户按下它时,它会显示一个 UIPickerView,它是从一个数组填充的。

是否可以在pickerView的顶部有搜索栏,以便用户在pickerView中进行搜索?

我以前没有见过这样做,所以不知道是否可行?

提前致谢。

【问题讨论】:

    标签: swift uitextfield uisearchbar uipickerview


    【解决方案1】:

    UIPickerView 真的意味着一些选项 - 如果您需要展示具有更多选项的东西,我建议使用带有搜索栏的表格视图。 Search Bar Tutorial 是一个好的开始。

    【讨论】:

    • 感谢您的信息。由于这个确切的原因,我在这里确实有另一个关于如何从 textField 到 table view 的问题。你能帮我理解我该怎么做吗?
    • 您需要有一个单独的带有表格视图和搜索栏的故事板;现在您可以从父视图控制器(包含文本字段)和表视图控制器(包含搜索栏)创建一个 segue - 从一个到另一个,我将首先搜索“以编程方式执行 Segue”并得到一些提示。如果您想在用户关注文本字段时执行操作,请查看UITextFieldDelegate(特别是textFieldDidBeginEditing)。
    【解决方案2】:

    这是我在最近的项目中使用的一个简单的解决方案。首先你需要专注于以下几点。

    1. 尝试使用 UITextfield 进行更好的自定义
    2. 使用表格视图在主 viewController 类中轻松填充数据。
    3. 避免使用有点烦人且过时的 segue 东西。
    4. 尽量让您的代码更真实、更轻松。

    首要任务 :- 我正在使用 Xcode 7.2.2 和 Swift 2.1

    使用原生过滤器方法过滤数组并重复使用。

    使用数组类型字典(Swift)的数组

    专注于以上几点.. :)

    这是我的课程文件。看一遍代码你就明白了……

    import UIKit
    
    class ComposeMessageClass: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
    var filtered = [[String : String]]()
    let customerNameForSearch: [[String : String]] = [["name": "Tuhin"], ["name": "Superman"], ["name" : "Rahul"], ["name": "Batman"], ["name": "Spiderman"]]
    let customerNameToSearchTemp = ["Tuhin", "Superman", "Rahul", "Batman", "Spiderman"]
    var searchActive: Bool = false
    @IBOutlet weak var autofillTable: UITableView!
    @IBOutlet weak var autofillTableView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.autofillTableView.hidden = true
        self.autofillTable.delegate = self
        self.autofillTable.dataSource = self
        self.autofillTable.backgroundColor = tableViewBackGroundColor
        self.autofillTable.separatorColor = tableViewSeperatorColor
        self.autofillTable.layer.borderColor = tableViewBorderColor
        }
    }
    
    override func viewWillAppear(animated: Bool) {
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func viewDidAppear(animated: Bool) {
    }
    
    func textFieldDidBeginEditing(textField: UITextField) {
    }
    
    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        var updatedTextString : NSString = textField.text! as NSString
        updatedTextString = updatedTextString.stringByReplacingCharactersInRange(range, withString: string)
        self.filtered.removeAll()
        self.customerNameToSearchTemp.filter({ (text) -> Bool in
            let tmp: NSString = text
            let range = tmp.rangeOfString(updatedTextString as String, options: NSStringCompareOptions.CaseInsensitiveSearch)
            if range.location != NSNotFound{
                let dataArr = ["name": tmp as String]
                filtered.append(dataArr)
    
            }
            return false
          }
        })
    
        if(filtered.count == 0){
    
            filtered = [["name" : "No results found"]]
            searchActive = true
        } else {
            searchActive = true;
        }
        self.autofillTable.reloadData()
        return true
    }
    
    func textFieldDidEndEditing(textField: UITextField) {
    
    }
    
    func textFieldShouldReturn(textField: UITextField) -> Bool {
       textField.resignFirstResponder()
        return true
    }
    
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(searchActive) {
            return self.filtered.count
        }
        return self.customerNameForSearch.count
    
    }
    internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell:UITableViewCell = self.autofillTable.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
        cell.backgroundColor = UIColor.clearColor()
        cell.textLabel!.textColor = tableViewCellTextColorGreen
        cell.textLabel!.textAlignment = .Center
        cell.selectionStyle = .None
        cell.textLabel!.font = UIFont(name: "System", size:17)
        if(searchActive){
            if filtered[indexPath.row]["name"]! == "No results found"{
                cell.textLabel!.text = self.filtered[indexPath.row]["name"]!
                cell.userInteractionEnabled = false
            }else{
                cell.userInteractionEnabled = true
                cell.textLabel?.text = self.filtered[indexPath.row]["name"]!
            }
        } else {
            cell.userInteractionEnabled = true
            cell.textLabel?.text = self.appDelegateObjForThisClass.customerNameForSearch[indexPath.row]["name"]!
        }
        return cell
    }
    internal func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        if(self.autofillTable.respondsToSelector(Selector("setSeparatorInset:"))){
            self.autofillTable.separatorInset = UIEdgeInsetsZero
        }
    
        if(self.autofillTable.respondsToSelector(Selector("setLayoutMargins:"))){
            self.autofillTable.layoutMargins = UIEdgeInsetsZero
        }
    
        if(cell.respondsToSelector(Selector("setLayoutMargins:"))){
            cell.layoutMargins = UIEdgeInsetsZero
        }
    }
    func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
        let cell  = tableView.cellForRowAtIndexPath(indexPath)
        cell?.backgroundColor = UIColor.clearColor()
        cell?.textLabel?.textColor = tableViewCellTextColorGreen
    }
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let cell  = tableView.cellForRowAtIndexPath(indexPath)
        cell?.backgroundColor = UIColor.blackColor()
        cell?.textLabel?.textColor = tableViewCellTextColorWhite
        self.selectedCustomerId.removeAll()
        if(searchActive){
            self.contactNameTxtFld.text = self.filtered[indexPath.row]["name]!
        }else{
            self.contactNameTxtFld.text = self.appDelegateObjForThisClass.customerNameForSearch[indexPath.row]["name"]!
        }
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?){
        self.view.endEditing(true)
    }
    }
    

    设置故事板的示例。

    谢谢。

    希望这会有所帮助。

    任何修改或建议我们的问题将不胜感激。

    【讨论】:

      【解决方案3】:
      1. 我为表格添加了一个自定义标题视图,其中包含一个设置为 searcontroller(searchbar) 的 textField 并以编程方式取消按钮,几乎没有对 tableView 进行自定义。
      2. 我添加了以下代码来过滤并获取更新的搜索结果

      ViewController 类:UIViewController,UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource{

      let speciality=["Andhra","Bhihar","uttharPradesh","kerala","karnataka","kashmir","thamilnadu","assam","jarkhand","dolapure","manjil","udaypoor","sholapoor","Atthapure","Barampure","Khasi"]
      
      var filteredArray = [String]()
      
      var shouldShowSearchResults = false
      
      var tableView:UITableView!
      
      var yaxis:CGFloat=10
      
      var txtdateOfOperation:UITextField!
      
      var searchTextField:UITextField!
      
      var cancelButton:UIButton!
      
      override func viewDidLoad() {
      
          let dateOfOperationLabel=UILabel(frame:CGRectMake(8,100,200,16))
          dateOfOperationLabel.text="State"
          dateOfOperationLabel.textColor=UIColor.blackColor()
          dateOfOperationLabel.textAlignment=NSTextAlignment.Left
          dateOfOperationLabel.font = UIFont.systemFontOfSize(13.0)
          dateOfOperationLabel.numberOfLines = 0;
          self.view.addSubview(dateOfOperationLabel)
      
          txtdateOfOperation=UITextField(frame: CGRectMake(8,130,300,28))
          txtdateOfOperation.borderStyle=UITextBorderStyle.RoundedRect
          txtdateOfOperation.returnKeyType=UIReturnKeyType.Done
          txtdateOfOperation.userInteractionEnabled=true
          txtdateOfOperation.keyboardType=UIKeyboardType.NumberPad
          self.view.addSubview(txtdateOfOperation)
      
          tableView=UITableView(frame: UIScreen.mainScreen().bounds, style: UITableViewStyle.Plain)
          tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
          tableView.delegate=self
          tableView.dataSource=self
          tableView.reloadData()
      
          let view=UIView(frame:CGRectMake(0,0,UIScreen.mainScreen().bounds.width,35))
      
          view.backgroundColor=UIColor.lightGrayColor()
      
          searchTextField=UITextField(frame:CGRectMake(8,3,view.bounds.width-70,28))
      
          searchTextField.borderStyle=UITextBorderStyle.RoundedRect
          searchTextField.returnKeyType=UIReturnKeyType.Done
          searchTextField.userInteractionEnabled=true
          searchTextField.delegate=self
          searchTextField.placeholder="Search Here..."
          searchTextField.clearButtonMode = .WhileEditing
      
          searchTextField.leftViewMode = UITextFieldViewMode.Always
      
          searchTextField.leftView = UIImageView(image: UIImage(named: "search-icon"))
      
          searchTextField.addTarget(self, action: #selector(searchTextFieldDidBeginEdit), forControlEvents: UIControlEvents.EditingChanged)
      
          view.addSubview(searchTextField)
      
          cancelButton=UIButton(frame:CGRectMake(view.bounds.width-65,3,70,28))
          cancelButton.setTitle("Cancel", forState: UIControlState.Normal)
          cancelButton.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)
          cancelButton.addTarget(self, action: #selector(searchBarCancelButton_Click), forControlEvents: UIControlEvents.TouchUpInside)
          cancelButton.userInteractionEnabled=false
      
          view.addSubview(cancelButton)
      
          tableView.tableHeaderView = view
      
          txtdateOfOperation.inputView=tableView
      
          searchTextField.inputView=tableView
      
          self.tableView.reloadData()
      
          }
      
      
      func textFieldDidBeginEditing(textField: UITextField) {
      
          shouldShowSearchResults = true
          cancelButton.userInteractionEnabled=true
          cancelButton.setTitleColor(UIColor(red: 51/255, green: 153/255, blue: 255/255, alpha: 1.0), forState: UIControlState.Normal)
          tableView.reloadData()
      }
      
      func textFieldDidEndEditing(textField: UITextField) {
         cancelButton.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)
      }
      
      func searchTextFieldDidBeginEdit(textField:UITextField) {
      
        if let searchText=textField.text{
      
          filteredArray = speciality.filter({ (country) -> Bool in
              let countryText: NSString = country
      
              return (countryText.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch).location) != NSNotFound
          })
              tableView.reloadData()
          }
      }
      
      func searchBarCancelButton_Click(){
          searchTextField.text=nil
          searchTextField.resignFirstResponder()
          shouldShowSearchResults = false
          tableView.reloadData()
      }
      
      
      func textFieldShouldReturn(textField: UITextField) -> Bool {
          textField.resignFirstResponder()
          return true
      }
      
      
      func numberOfSectionsInTableView(tableView: UITableView) -> Int {
          return 1
      }
      
      
      func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          if shouldShowSearchResults {
              return filteredArray.count
          }
          else {
              return speciality.count
          }
      }
      
      
      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
          let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
      
          if shouldShowSearchResults {
              cell.textLabel?.text = filteredArray[indexPath.row]
          }
          else {
              cell.textLabel?.text = speciality[indexPath.row]
          }
      
          return cell
      }
      
      
      func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
          return 60.0
      }
      
      func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
      
      
          if shouldShowSearchResults{
              txtdateOfOperation.text=filteredArray[indexPath.row]
              searchTextField.text=nil
              searchTextField.resignFirstResponder()
              txtdateOfOperation.resignFirstResponder()
              shouldShowSearchResults=false
              filteredArray=[String]()
              tableView.reloadData()
          }
          else{
      
              txtdateOfOperation.text=speciality[indexPath.row]
              searchTextField.resignFirstResponder()
              tableView.resignFirstResponder()
              txtdateOfOperation.resignFirstResponder()
          }
      }
      

      }

      我测试了它并且它工作得很好

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-26
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        相关资源
        最近更新 更多