Zack Blauvelt
Zack Blauvelt

Reputation: 29

Image not behaving accurately in data search results on TableView

I have data coming from Firebase and when the data is loaded I either want the an image to be hidden or shown based on some logic in my custom cell. It works perfectly fine when the data isn't being filtered but the second I type in the search bar or change the scope bar to a different index the image doesn't behave right. For example: Index 0 should not have the image and index 1 should. Which is how it displays when it first loads. However, when I search I know the previous index 1 (now index 0) should still have it's image but it doesn't. BUT if I click to go to the detail controller it brings me to the right page. It's like it loads all the accurate info but does the logic on the original index 0. I would love some help as I have been searching for an answer FOREVER. Thank you in advance!

tableViewCell:

class SearchTalentCell: UITableViewCell {
@IBOutlet weak var userProfileImage: UIImageView!
@IBOutlet weak var talentUserName: UILabel!
@IBOutlet weak var selectedImg: UIImageView!
@IBOutlet weak var inviteSentImg: UIImageView!
var prospectRef: FIRDatabaseReference!
//@IBOutlet weak var radioButton: UIButton!
var currentTalent: UserType!
//var delegate: SearchCellDelegate?

func setTalent(talent: UserType) {
    currentTalent = talent
    currentTalent.userKey = talent.userKey
}

override func awakeFromNib() {
    super.awakeFromNib()
    let tap = UITapGestureRecognizer(target: self, action: #selector(selectTapped))
    tap.numberOfTapsRequired = 1
    selectedImg.addGestureRecognizer(tap)
    selectedImg.isUserInteractionEnabled = true
}

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) {
    prospectRef = Cast.REF_PRE_PRODUCTION_CASTING_POSITION.child(ProjectDetailVC.currentProject).child(FIRDataCast.prospect.rawValue).child(CastingDetailVC.positionName).child(user.userKey)
    //setTalent(talent: user)
    self.talentUserName.text = "\(user.firstName) \(user.lastName)"
    //self.inviteSentImg.image = UIImage(named: "inviteSent")
    //user.adjustSearchSelected(talent: user, radioButton: radioButton)
    prospectRef.observeSingleEvent(of: .value, with: { (snapshot) in
        if let _ = snapshot.value as? NSNull {
            self.inviteSentImg.isHidden = true
            print("**Image hidden")
        } else {
            self.inviteSentImg.image = UIImage(named: "inviteSent")
            print("**Image shown")
        }
    })

    //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)
                        }
                    }
                }
            })
        }
    }



}

Viewcontroller:

class SearchTalentVC: UITableViewController/*, SearchCellDelegate*/ {

var searchingRole = [Cast]()
var unfilteredTalent = [UserType]()
var filteredTalent = [UserType]()
var selectedTalent = [UserType]()
var matchingTalentUserKeys = [String]()
var isFiltered = false
var prospectRef: FIRDatabaseReference!
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
    searchController.searchResultsUpdater = 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 cellIdentifier = "userSearchCell"
    if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SearchTalentCell {
        var talent: UserType
        if isSearching() {
            print("we are searching")
            talent = self.filteredTalent[indexPath.row]

            print("indexPath: \(indexPath.row)")
        } else {
            print("we are not searching")
            talent = self.unfilteredTalent[indexPath.row]

        }

        if let imageURL = talent.profileImage {
            if let img = SearchTalentVC.userProfileImageCache.object(forKey: imageURL as NSString) {
                cell.configureCell(user: talent, img: img)

            } else {
                cell.configureCell(user: talent)

                //cell.delegate = self
            }
            return cell
        } else {
            cell.configureCell(user: talent)
            //cell.delegate = self
            return SearchTalentCell()
        }
    } else {
        return SearchTalentCell()
    }
}

extension SearchTalentVC: UISearchResultsUpdating {
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        filterContentForSearchText(searchController.searchBar.text!, scope: scope)
        self.tableView.reloadData()
    }


}


extension SearchTalentVC: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
    }
}

Upvotes: 0

Views: 58

Answers (1)

Manish Mahajan
Manish Mahajan

Reputation: 2082

If you are hidding image in If part then you should put logic of showing image also in else block. See if this solve your problem.

if let _ = snapshot.value as? NSNull {
    self.inviteSentImg.isHidden = true
    print("**Image hidden")
} else {
    self.inviteSentImg.isHidden = false
    self.inviteSentImg.image = UIImage(named: "inviteSent")
    print("**Image shown")
}

Upvotes: 1

Related Questions