searchBar 过滤 tableViewCells didSelectItemAt indexPath 显示在 navigationBar Title

Posted

技术标签:

【中文标题】searchBar 过滤 tableViewCells didSelectItemAt indexPath 显示在 navigationBar Title【英文标题】:searchBar filtered tableViewCells didSelectItemAt indexPath display in navigationBar Title 【发布时间】:2017-05-19 21:48:32 【问题描述】:

enter image description here我在从 searchBar 过滤的 tableView 单元格中实现 didSelectRowAtIndexPath 时遇到问题。当我根据搜索栏 textDidChange 更新 tableView 列表,并对另一个 ViewController 执行 show segue 时,navigationBar Title 始终显示未过滤的 tableViews indexPath 0。换句话说,我想让导航标题显示来自的文本搜索结果 tableView 的 didSelectAtIndex (不是来自未过滤的 tableView 的原始 indexPath 单元格文本)。希望这是有道理的,并提前感谢!

// viewDidLoad method
    override func viewDidLoad() 
        super.viewDidLoad()

        searchBar.searchBarStyle = UISearchBarStyle.prominent
        searchBar.placeholder = " Search Places..."
        searchBar.sizeToFit()
        searchBar.isTranslucent = false
        searchBar.backgroundImage = UIImage()
        searchBar.delegate = self
        searchBar.returnKeyType = UIReturnKeyType.done
        navigationItem.titleView = searchBar

        ref = FIRDatabase.database().reference()
        fetchPlaces()

        placesClient = GMSPlacesClient.shared()
        locationManager.requestAlwaysAuthorization()

        tableView.allowsMultipleSelectionDuringEditing = true

    

    var placeList = [Place]()
    var placesDictionary = [String: Place]()

    // fetch places for tableView method
    func fetchPlaces() 
        let uid = FIRAuth.auth()?.currentUser?.uid
        let ref = FIRDatabase.database().reference().child("users").child(uid!).child("Places")
        ref.observe(.childAdded, with:  (snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject] 
                let place = Place()
                place.setValuesForKeys(dictionary)

                if let addedBy = place.addedBy 
                    self.placesDictionary[addedBy] = place
                    self.placeList.insert(place, at: 0)
                
                //this will crash because of background thread, so lets call this on dispatch_async main thread
                DispatchQueue.main.async(execute: 
                    self.tableView.reloadData()
                )
              
        , withCancel: nil)
    

    // search variables
        lazy var searchBar:UISearchBar = UISearchBar()
        var isSearching = false
        var filteredData = [Place]()

    // searchBar method
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
            if searchBar.text == nil || searchBar.text == "" 
                isSearching = false
                view.endEditing(true)
                tableView.reloadData()
             else 
                isSearching = true
                filteredData = placeList.filter($0.place?.range(of: searchBar.text!) != nil)
                tableView.reloadData()
            
        

    // tableView methods
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
            if isSearching 
                return filteredData.count
            
            return placeList.count
        

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
            let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
            if isSearching 
                cell.textLabel?.text = filteredData[indexPath.row].place
             else 
            cell.textLabel?.text = placeList[indexPath.row].place
            
            return cell
        

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    let placeDetailsVC = CurrentUserPlaceDetailsVC()
    if isSearching == false 
    placeDetailsVC.navigationTitle = placeList[(indexPath.row)].place
    show(placeDetailsVC, sender: self)
     else 
        placeDetailsVC.navigationTitle = filteredData[(indexPath.row)].place
        show(placeDetailsVC, sender: self)
        
    
 

【问题讨论】:

【参考方案1】:

在即将到来的 ViewController 中创建一个字符串。

class CurrentUserPlaceDetailsVC: UIViewController 
    var navigationTitle: String?

    override func viewDidLoad()
        super.viewDidLoad()
        self.navigationItem.title = navigationTitle
    

现在,与其将标题直接分配给 navigationBar,不如先将其分配给该字符串,然后再分配给 viewController 的 viewDidLoad 方法中的 navigationBar。

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let placeDetailsVC = CurrentUserPlaceDetailsVC()
        // Get Cell Label
        placeDetailsVC.navigationTitle = placeList[indexPath.row].place
        show(placeDetailsVC, sender: self)

     

【讨论】:

谢谢,但还是不行...我想知道当searchBar显示过滤后的tableView时是否需要重置indexPath?我添加了一张图片供参考。 你能告诉我你的数据源方法实现吗? numberOfRows 和 cellForRow 也是。 还有一件事,你 tableView 是否也显示了过滤结果?如果不是,那么您是在寻找过滤 tableView 的方法,还是您当前正在成功显示过滤器但想将数据从选择单元格传递到下一个视图控制器? 当然,我在原始帖子中更新了我的代码示例以显示相关方法。我的 tableView 在 searchBar textDidChange 上成功显示了过滤结果,但是当点击过滤结果单元格时,它没有将正确的单元格文本推送到下一个 VC 导航栏标题。所以在我附加的图片中,当我输入“B”并且表格过滤器显示泰国曼谷时点击“泰国曼谷”它会推送到下一个 VC,但导航栏标题不显示“泰国曼谷”。而是显示原始未过滤的 indexPath.item 为 0(未过滤的 tableView 中的第一项)。 想出了我自己的问题......不确定这是否是最好的方法,但它现在有效。请参阅我的 didSelectRowAt indexPath 方法的编辑代码。

以上是关于searchBar 过滤 tableViewCells didSelectItemAt indexPath 显示在 navigationBar Title的主要内容,如果未能解决你的问题,请参考以下文章