Firebase Swift-实时更新在结果被搜索控制器过滤时不起作用



我正在使用Swift和Firebase制作iOS应用程序。视图控制器检索/观察项目并将其存储在项目数组中。项目单元具有 和 - 按钮,可以使用其Indexpath对项目的数量进行更新。

如果我使用搜索控制器进行过滤项目,则可以将搜索结果存储在过滤deDItems数组中。我正在尝试更新这些过滤的项目的数量,但是当我点击 或 - 按钮时,它们只能更新一次,并且在搜索结果视图中不显示更新(没有单独的视图,我在同一视图中使用数据源显示过滤码头(。即使我多次击中它,它总是一次更新一次。

通过取消搜索栏返回常规视图后,我看到1上下的搜索栏取决于我敲击的按钮。有人知道这可能导致问题吗?

class ItemsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, SortTypeTableViewControllerDelegate, ItemListCellDelegate {
private var items = [Item]()
private var filteredItems = [Item]()
private func retrieveFirebaseData(sortType: ItemSort.SortType, sortOrder: ItemSort.SortOrder) {
guard let currentUser = Auth.auth().currentUser else {
  return print("user not logged in")
}
let itemsRef = DatabaseReferenceHelper.usersRef.child(currentUser.uid).child("items")
itemsRef.queryOrdered(byChild: sortType.rawValue).observe(.value) { (snapshot) in
  var newItems: [Item] = []
  for item in snapshot.children {
    let item = Item(snapshot: item as! DataSnapshot)
    if self.displayFavoritesOnly == true {
      if item.favorite == true {
        newItems.append(item)
      }
    } else {
      newItems.append(item)
    }
  }
  self.items = sortOrder == .ascending ? newItems : newItems.reversed()
  self.collectionView.reloadData()
}
}
// this is from item cell delegate
func increaseDecreaseQuantity(_ sender: ItemListCell, increment: Bool) {
  guard let tappedIndexPath = collectionView.indexPath(for: sender) else {
    return
  }
  let item: Item
  item = isFiltering() ? filteredItems[tappedIndexPath.item] : items[tappedIndexPath.item]
  let updatedQuantity = increment == true ? item.quantity + 1 : item.quantity - 1
  guard let currentUser = Auth.auth().currentUser else {
    return print("user not logged in")
  }
  let itemsRef = DatabaseReferenceHelper.usersRef.child(currentUser.uid).child("items")
  itemsRef.child(item.key).updateChildValues(["quantity": updatedQuantity])
}

// Here's the search logic I learned from Ray Wenderlich
private func searchBarIsEmpty() -> Bool {
  return searchController.searchBar.text?.isEmpty ?? true
}
private func filterContentForSearchText(_ searchText: String, scope: String = "All") {
  filteredItems = items.filter({$0.title.lowercased().contains(searchText.lowercased())})
  collectionView.reloadData()
}
private func isFiltering() -> Bool {
  return searchController.isActive && !searchBarIsEmpty()
}

extension ItemsViewController: UISearchResultsUpdating {
  func updateSearchResults(for searchController: UISearchController) {
    filterContentForSearchText(searchController.searchBar.text!)
  }
}

每个 & amp; - 。重新加载收集视图后,将看到新的更新。

我解决了问题。我要做的就是在retirevefirebaseadata函数中添加另一个称为" searchText"的参数,并在FilterContentForsearchText中使用该函数。

基本上,我需要在观察方法下过滤物品,例如以下代码。

private func retrieveFirebaseData(sortType: ItemSort.SortType, sortOrder: ItemSort.SortOrder, searchText: String?) {
  guard let currentUser = Auth.auth().currentUser else {
    return print("user not logged in")
  }

  let itemsRef = DatabaseReferenceHelper.usersRef.child(currentUser.uid).child("items")
  itemsRef.queryOrdered(byChild: sortType.rawValue).observe(.value) { (snapshot) in
    if let searchText = searchText {
      // FILTER HERE
      self.filteredItems = self.items.filter({$0.title.lowercased().contains(searchText.lowercased())})
    } else {
      var newItems: [Item] = []
      for item in snapshot.children {
        let item = Item(snapshot: item as! DataSnapshot)
        if self.displayFavoritesOnly == true {
          if item.favorite == true {
            newItems.append(item)
          }
        } else {
          newItems.append(item)
        }
      }        
      self.items = sortOrder == .ascending ? newItems : newItems.reversed()
    }
    self.collectionView.reloadData()
  }
}
private func filterContentForSearchText(_ searchText: String, scope: String = "All") {
  retrieveFirebaseData(sortType: itemSortType, sortOrder: itemSortOrder, searchText: searchText)
}

"用于过滤项目的filterContentForsearchText"功能,然后重新加载表:

private func filterContentForSearchText(_ searchText: String, scope: String = "All") {
  filteredItems = items.filter({$0.title.lowercased().contains(searchText.lowercased())})
  collectionView.reloadData()
}

最新更新