【问题标题】:didSelectRowAtIndexPath indexpath after filter UISearchController - Swift过滤后的 didSelectRowAtIndexPath 索引路径 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
            }
        }
    }

【问题讨论】:

    标签: ios uitableview swift


    【解决方案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 进行详细视图搜索(谓词)。

      【讨论】:

        猜你喜欢
        • 2019-04-09
        • 1970-01-01
        • 2022-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-25
        • 1970-01-01
        相关资源
        最近更新 更多