让这个工作变得很麻烦。我有一个存储在Firebase中的人员列表。我试图允许用户在数据未经过滤的情况下选择单个行,但是可以选择根据他们在之前的vc上指定的条件进行过滤。现在,它的设置方式是每次单击单选按钮时都会通知firebase,并且数据会更新以显示该人正在被选中。当数据未经过滤时,一切都很好。当过滤器打开时,我有两个问题。 1)当按下按钮时,会通知firebase - 但只有一次 - 如果再次按下按钮取消选择它就像按钮从未被按下一样。但是我知道它已被确认,因为我添加了indexPath的userKey的print语句,因此我无法弄清楚为什么它不会像数据未经过滤时那样发送到firebase。
我的第二个问题是无线电按钮不会像数据未经过滤那样改变它的数据。 我一直在研究和研究,找不到任何东西。真的希望有第二眼看看我是否错过了什么或做错了什么。
这是我的表视图单元格:
protocol SearchCellDelegate {
func didTapRadioButton(userKey: String, searchSelected: String, radioButton: UIButton)}
class SearchTalentCell: UITableViewCell {
@IBOutlet weak var userProfileImage: UIImageView!
@IBOutlet weak var talentUserName: UILabel!
@IBOutlet weak var radioButton: UIButton!
var currntTalent: UserType!
var delegate: SearchCellDelegate?
func setTalent(talent: UserType) {
currntTalent = talent
currntTalent.userKey = talent.userKey
currntTalent.searchSelected = talent.searchSelected
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
@IBAction func radioButtonTapped(_ sender: Any) {
delegate?.didTapRadioButton(userKey: currntTalent.userKey, searchSelected: currntTalent.searchSelected!.rawValue, radioButton: radioButton)
}
func configureCell(user: UserType, img: UIImage? = nil) {
setTalent(talent: user)
self.talentUserName.text = "\(user.firstName) \(user.lastName)"
user.adjustSearchSelected(talent: user, radioButton: radioButton)
//Image Caching
if img != nil {
self.userProfileImage.image = img
} else {
if let imageURL = user.profileImage {
let ref = FIRStorage.storage().reference(forURL: imageURL)
ref.data(withMaxSize: 2 * 1024 * 1024, completion: { (data, error) in
if error != nil {
print("ZACK: Unable to download image from Firebase Storage")
} else {
print("ZACK: Image downloaded from Firebase Storage")
if let imgData = data {
if let img = UIImage(data: imgData) {
self.userProfileImage.image = img
SearchTalentVC.userProfileImageCache.setObject(img, forKey: imageURL as NSString)
}
}
}
})
}
}
}}
user.adjustSearchSeleced func只是看到Firebase中的内容(是或否)并放置适当的图像。
这是我的ViewController - 对不起,过滤功能有点冗长。
class SearchTalentVC: UITableViewController, SearchCellDelegate {
var searchingRole = [Cast]()
var unfilteredTalent = [UserType]()
var filteredTalent = [UserType]()
var selectedTalent = [UserType]()
var matchingTalentUserKeys = [String]()
var isFiltered = false
static var userProfileImageCache: NSCache<NSString, UIImage> = NSCache()
let searchController = UISearchController(searchResultsController: nil)
//@IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Talent"
searchController.searchBar.barStyle = .black
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.scopeButtonTitles = ["All", "Role Specific"]
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.delegate = self
getTalentProfiles()
}
func searchBarIsEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredTalent = unfilteredTalent.filter({ (talent : UserType) -> Bool in
let doesTalentMatch = (scope == "All") || doesUserKeyMatch(talent: talent.userKey)
if searchBarIsEmpty() {
return doesTalentMatch
} else {
let fullName = "\(talent.firstName) \(talent.lastName)"
return doesTalentMatch && fullName.lowercased().contains(searchText.lowercased())
}
})
tableView.reloadData()
}
func doesUserKeyMatch(talent: String) -> Bool {
self.filterRoleFeature()
return matchingTalentUserKeys.contains(talent)
}
func isSearching() -> Bool {
let searchBarScopeIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0
return searchController.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if isSearching() {
return filteredTalent.count
} else {
return unfilteredTalent.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let talent: UserType
if isSearching() {
talent = self.filteredTalent[indexPath.row]
} else {
talent = self.unfilteredTalent[indexPath.row]
}
let cellIdentifier = "userSearchCell"
// Configure the cell...
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SearchTalentCell {
if let imageURL = talent.profileImage {
if let img = SearchTalentVC.userProfileImageCache.object(forKey: imageURL as NSString) {
cell.configureCell(user: talent, img: img)
cell.delegate = self
} else {
cell.configureCell(user: talent)
cell.delegate = self
}
return cell
} else {
cell.configureCell(user: talent)
cell.delegate = self
return SearchTalentCell()
}
} else {
return SearchTalentCell()
}
}
//MARK: Filter through role needs
func filterRoleFeature() {
//Filters are in order of how they are checked. Every talent that matches age will then be checked by height and so on.
var ageFilter = [UserType]()
var heightFilter = [UserType]()
var ethnicityFilter = [UserType]()
var bodyTypeFilter = [UserType]()
var eyeColorFilter = [UserType]()
var hairColorFilter = [UserType]()
var hairLengthFilter = [UserType]()
print("Filtering....")
let role = searchingRole[0]
//MARK: Filtering out age limit
let roleAgeMin = convertStringToInt(string: role.ageMin)
let roleAgeMax = convertStringToInt(string: role.ageMax)
//MARK: If only a minimum age requirement
if roleAgeMin > 0 && roleAgeMax <= 0 {
for talent in unfilteredTalent {
let talentAge = convertStringToInt(string: talent.age)
if talentAge >= roleAgeMin {
ageFilter.append(talent)
}
}
} else if roleAgeMin <= 0 && roleAgeMax > 0 {
for talent in unfilteredTalent {
let talentAge = convertStringToInt(string: talent.age)
if talentAge <= roleAgeMax {
ageFilter.append(talent)
}
}
} else if roleAgeMin > 0 && roleAgeMax > 0 {
for talent in unfilteredTalent {
let talentAge = convertStringToInt(string: talent.age)
if talentAge >= roleAgeMin && talentAge <= roleAgeMax {
ageFilter.append(talent)
}
}
} else {
for talent in unfilteredTalent {
ageFilter.append(talent)
}
}
//MARK: Filtering out height requirement from age filter
let roleHeightMin = convertStringToInt(string: role.heightMin)
let roleHeightMax = convertStringToInt(string: role.heightMax)
if roleHeightMin > 0 && roleAgeMax <= 0 {
for talent in ageFilter {
let talentHeight = convertStringToInt(string: talent.height)
if talentHeight >= roleHeightMin {
heightFilter.append(talent)
}
}
} else if roleHeightMin <= 0 && roleHeightMax > 0 {
for talent in ageFilter {
let talentHeight = convertStringToInt(string: talent.height)
if talentHeight <= roleHeightMax {
heightFilter.append(talent)
}
}
} else if roleHeightMin > 0 && roleHeightMax > 0 {
for talent in ageFilter {
let talentHeight = convertStringToInt(string: talent.height)
if talentHeight >= roleHeightMin && talentHeight <= roleHeightMax {
heightFilter.append(talent)
}
}
} else {
for talent in ageFilter {
heightFilter.append(talent)
}
}
//MARK: Filtering out ethnicity requirements
let roleEthnicity = role.ethnicity?.rawValue
if roleEthnicity == "" || roleEthnicity == nil {
for talent in heightFilter {
ethnicityFilter.append(talent)
}
} else {
for talent in heightFilter {
if roleEthnicity == talent.ethnicity?.rawValue {
ethnicityFilter.append(talent)
}
}
}
//MARK: Filtering out body type requirements
let roleBodyType = role.bodyType?.rawValue
if roleBodyType == "" || roleBodyType == nil {
for talent in ethnicityFilter {
bodyTypeFilter.append(talent)
}
} else {
for talent in ethnicityFilter {
if roleBodyType == talent.bodyType?.rawValue {
bodyTypeFilter.append(talent)
}
}
}
//MARK: Filtering out eye color requirements
let roleEyeColor = role.eyeColor?.rawValue
if roleEyeColor == "" || roleEyeColor == nil {
for talent in bodyTypeFilter {
eyeColorFilter.append(talent)
}
} else {
for talent in bodyTypeFilter {
if roleEyeColor == talent.eyeColor?.rawValue {
eyeColorFilter.append(talent)
}
}
}
//MARK: Filtering out hair color requirements
let roleHairColor = role.hairColor?.rawValue
if roleHairColor == "" || roleHairColor == nil {
for talent in eyeColorFilter {
hairColorFilter.append(talent)
}
} else {
for talent in eyeColorFilter {
if roleHairColor == talent.hairColor?.rawValue {
hairColorFilter.append(talent)
}
}
}
//MARK: Filtering out hair length requirements
let roleHairLength = role.hairLength?.rawValue
if roleHairLength == "" || roleHairLength == nil {
for talent in hairColorFilter {
hairLengthFilter.append(talent)
}
} else {
for talent in hairColorFilter {
if roleHairLength == talent.hairLength?.rawValue {
hairLengthFilter.append(talent)
}
}
}
//MARK: Filtering out hair type requirements - last filter - goes to roleTalentFilter [UserType]
let roleHairType = role.hairType?.rawValue
if roleHairType == "" || roleHairType == nil {
for talent in hairLengthFilter {
self.filteredTalent.append(talent)
self.matchingTalentUserKeys.append(talent.userKey)
}
} else {
for talent in hairLengthFilter {
if roleHairType == talent.hairType?.rawValue {
self.filteredTalent.append(talent)
self.matchingTalentUserKeys.append(talent.userKey)
}
}
}
}
//Convert optional string to int
func convertStringToInt(string: String?) -> Int {
var int = 0
if let str = string {
if let stringToInt = Int(str) {
int = stringToInt
}
}
return int
}
//Get all users for Search
func getTalentProfiles() {
UserType.REF_USERS.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
self.unfilteredTalent.removeAll()
for snap in snapshot {
print("SNAP: \(snap)")
//If the id matches the id from projects then it will be added to userProjectsDetails Array
if let userDetailsDict = snap.value as? Dictionary<String, String> {
let key = snap.key
let userDetails = UserType(userKey: key, userData: userDetailsDict)
self.unfilteredTalent.append(userDetails)
if userDetails.searchSelected == SearchSelected.yes {
self.selectedTalent.append(userDetails)
}
}
}
}
self.tableView.reloadData()
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "searchToProfile" {
if let indexPath = tableView.indexPathForSelectedRow {
let destinationController = segue.destination as! ProfileVC
if isSearching() {
destinationController.currentUserKey = filteredTalent[indexPath.row].userKey
} else {
destinationController.currentUserKey = unfilteredTalent[indexPath.row].userKey
}
}
}
}
func didTapRadioButton(userKey: String, searchSelected: String, radioButton: UIButton) {
if searchSelected == SearchSelected.yes.rawValue {
let searchSelected = [FIRUserData.searchSelected.rawValue: SearchSelected.no.rawValue]
UserType.REF_USERS.child(userKey).updateChildValues(searchSelected)
print("button hit \(userKey) NO")
} else if searchSelected == SearchSelected.no.rawValue {
let searchSelected = [FIRUserData.searchSelected.rawValue: SearchSelected.yes.rawValue]
UserType.REF_USERS.child(userKey).updateChildValues(searchSelected)
print("button hit \(userKey) YES")
} else {
let searchSelected = [FIRUserData.searchSelected.rawValue: SearchSelected.yes.rawValue]
UserType.REF_USERS.child(userKey).updateChildValues(searchSelected)
}
}
}
extension SearchTalentVC: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
extension SearchTalentVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
任何帮助都将非常感谢!谢谢。