过滤后的 didSelectRowAtIndexPath 索引路径 UISearchController - Swift

Posted

技术标签:

【中文标题】过滤后的 didSelectRowAtIndexPath 索引路径 UISearchController - Swift【英文标题】:didSelectRowAtIndexPath indexpath after filter UISearchController - Swift 【发布时间】:2015-04-24 19:00:58 【问题描述】:

我正在一个分区表中实现一个带有 UISearchController 的搜索栏。到目前为止一切顺利。

主要问题是,当过滤后的结果出现时,它是一个全新的表,没有节,行也更少。

When selecting the row, I perform a segue to that position in the array, but the detailed view is expecting that exact row or index from the main array, which I can't get from the filtered array of objects, which may在 300 个元素中为 [0] [1] [2]。

我想我可以将所选对象与主数组进行比较,并假设没有重复项,从那里获取索引并将其传递……但这些对我来说似乎效率很低。

在联系人应用程序中过滤联系人时,Apple 做了类似的事情(不幸的是我不知道如何)。他们如何传递联系对象?这几乎就是我的目标。

在这里,我让您了解一下我正在做的事情:

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

        if(self.resultSearchController.active) 
            customerAtIndex = indexPath.row // Issue here
            performSegueWithIdentifier("showCustomer", sender: nil)
        
        else 
            customerAtIndex = returnPositionForThisIndexPath(indexPath, insideThisTable: tableView)
            performSegueWithIdentifier("showCustomer", sender: nil)
        
    

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        if segue.identifier == "showCustomer" 
            if let destination = segue.destinationViewController as? CustomerDetailViewController 
                destination.newCustomer = false
                destination.customer = self.customerList[customerAtIndex!]
                destination.customerAtIndex = self.customerAtIndex!
                destination.customerList = self.customerList
            
        
    

【问题讨论】:

【参考方案1】:

你可以用另一种方式来做,这是一个技巧,但它有效。首先更改您的didSelectRowAtIndexPath 如下:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
        var object :AnyObject?
        if(self.resultSearchController.active) 
            object = filteredArray[indexPath.row]
        
        else 
            object = self.customerList[indexPath.row]
        

        performSegueWithIdentifier("showCustomer", sender: object)
    

现在,在prepareForSegue 中,取回对象并将其发送到您的详细视图控制器

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        if segue.identifier == "showCustomer" 
        if let destination = segue.destinationViewController as? CustomerDetailViewController 
            destination.newCustomer = false
            destination.customer = sender as! CustomerObject
            destination.customerAtIndex = self.customerList.indexOfObject(destination.customer)
            destination.customerList = self.customerList
        
    

【讨论】:

感谢您的详细评论,我刚刚更新了 prepareForSegue。这样您就可以更全面地了解我在做什么。 @HelenWood 我更新了我的答案。我不知道你为什么需要customerAtIndex,我不知道它是什么,所以把它留在那里。 再次感谢您。索引处的客户是正在传递给接收者视图的当前客户......基本上,只需在目的地设置属性以匹配所选客户。 知道了。更新答案。 在我看来,您应该只需要customer 对象。【参考方案2】:

这是我在代码中使用的技巧,我基本上是从filteredObjects 数组中加载tableView,所以indexPath 总是正确的:

  var selectedObject: Object?

  private var searchController: UISearchController!
  private var allObjects: [Object]? 
    didSet 
      filteredObjects = allObjects
    
  
  private var filteredObjects: [Object]? 
    didSet 
      NSOperationQueue.mainQueue().addOperationWithBlock 
        self.tableView.reloadData()
      
    
  

  override func viewDidLoad() 
    super.viewDidLoad()

    loadData  objects in
      self.allObjects = objects
    
  

  // MARK:- UITableView

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return filteredObjects?.count ?? 0
  

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
    cell.textLabel?.text = filteredObjects?[indexPath.row].name
    return cell
  

  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    selectedObject = filteredObjects?[indexPath.row]
  

  // MARK:- UISearchBarDelegate

  func searchBar(searchBar: UISearchBar, textDidChange searchText: String) 

    if !searchText.isEmpty 
      filteredObjects = allObjects?.filter $0.name.lowercaseString.rangeOfString(searchText.lowercaseString) != nil 
     else 
      filteredObjects = allObjects
    

【讨论】:

【参考方案3】:

将新属性NSMutableArray *searchArray 添加到您的表视图类,然后在-(void)filterContentForSearchText:scope: 方法中将所有搜索结果传递给该数组。之后,您将能够在tableView:didSelectRowAtIndexPath: 中获取所选对象self.searchArray[indexPath.row]

【讨论】:

谢谢你 Nyfa,这也是一个好方法,你能扩展这个或发布一个 sn-p 吗?我将不胜感激。【参考方案4】:

我看到了两种解决方案 - 1) 为什么不让详细视图在过滤数组而不是主数组中查找行或索引。我猜你只关心你想要详细使用的那一行中的对象。 2)使数组中的每个对象都有一个唯一的id。通过 segue 传递选择时的唯一 id,并在主数组中为该 id 进行详细视图搜索(谓词)。

【讨论】:

以上是关于过滤后的 didSelectRowAtIndexPath 索引路径 UISearchController - Swift的主要内容,如果未能解决你的问题,请参考以下文章

重置剑道多过滤器复选框数据源以反映过滤后的数据

过滤后的 Primefaces 数据表排序

在 R 中使用 dplyr 进行过滤时,为啥过滤掉的变量级别会保留在过滤后的数据中? [复制]

ant design中对dataSource执行过滤功能后获取组件表中过滤后的数据

django模板:过滤后的点

Ng-显示过滤后的搜索是不是为空?