Vapidant
Vapidant

Reputation: 2682

Dequeue Reusable Cell crashes when calling dequeued cell

I am attempting to have a table view that lists multiple things and allows a user to go through and select multiple cells with checkboxes. My code works up until a certain point, the problem is that the app crashes with the following error

Fatal error: Unexpectedly found nil while unwrapping an Optional value

whenever I call the following code

swift let currentCell = recommendToFriendTableView.cellForRow(at: selectedRow[i]) as? RecommendToFriendsTableViewCell

Here is the method where we set up the cells

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if (tableView == self.friendListTableView) {


            let cell:  FriendListTableViewCell = tableView.dequeueReusableCell(withIdentifier: "FriendListCell") as! FriendListTableViewCell

            let rowNumber = (indexPath as NSIndexPath).row
            var name = ""
            if searchActive {
                name = filtered[rowNumber]
            }
            else {
                name = names[rowNumber]
            }
            cell.friendNameLabel.text = name
            cell.friendNameLabel.backgroundColor = tableViewBgColor
            cell.friendNameLabel.textColor = textColor
            cell.recommendToFriendButton.layer.borderWidth = 1
            cell.recommendToFriendButton.layer.borderColor = tableViewBgColor.cgColor
            cell.recommendToFriendButton.layer.cornerRadius = 6
            cell.recommendToFriendButton.backgroundColor = buttonBgColor
            cell.backgroundColor = tableViewBgColor
            //set target for buttons
            cell.recommendToFriendButton.tag = rowNumber
            cell.recommendToFriendButton.addTarget(self, action:#selector(recommendToFriendButtonClicked), for: UIControl.Event.touchUpInside)

            return cell
        }
        else {
            let cell: RecommendToFriendsTableViewCell = tableView.dequeueReusableCell(withIdentifier: "RecommendToFriendsCell") as! RecommendToFriendsTableViewCell
            let rowNumber = (indexPath as NSIndexPath).row
            // set the content view background color
            cell.contentView.backgroundColor = tableViewBgColor
            // set the text color
            cell.nameLabel.textColor = textColor
            var dict_friend = NSMutableDictionary()
            if searchActive {
                dict_friend = filteredFriendsArray[rowNumber]
            }
            else {
                dict_friend = friendsArray[rowNumber]
            }

            let name = dict_friend["name"] as! String
            cell.nameLabel.text = name
            let friendUID = dict_friend["uid"] as! String
            cell.friendID = friendUID
            let imageAddress = dict_friend["photo"] as? String

            if imageAddress != "unavailable" && imageAddress != nil && imageAddress != ""{



                //Swift forces us to wrap strings as optional to use them in logic
                if let imageURL = imageAddress as String? {

                    //Swift forces us to wrap strings as optional to use them in logic
                    if let image = imageURL as String? {

                        //We convert the string into a URL and get the image
                        let url = URL(string: image)
                        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in

                            if error != nil {
                                print(error!)
                                return
                            }

                            //We create a new async thread to download and update the image
                            DispatchQueue.main.async {
                                //imageView.image = UIImage(data: data!)
                                cell.photoImageView.image = UIImage(data:data!)

                            }
                        }).resume()
                    }



                } else {
                    cell.photoImageView!.image = UIImage(named: "placeholder-profile-male.png")
                }

            } else {
                cell.photoImageView!.image = UIImage(named: "placeholder-profile-male.png")
            }

            cell.checkBoxImageView.image = cell.checkBoxImageView.image!.withRenderingMode(.alwaysTemplate)
            cell.checkBoxImageView.tintColor = textColor
            // Style the profile photo to show in a circle
            cell.photoImageView.layer.borderWidth = 0
            cell.photoImageView.layer.borderColor = tableViewBgColor.cgColor
            // Set cornerRadius = a square UIImageView frame size width / 2
            // In our case, UIImageView height = width = 60 points
            cell.photoImageView.layer.cornerRadius = 30
            cell.photoImageView.clipsToBounds = true
            cell.selectionStyle = .none // to prevent cells from being "highlighted"
            return cell
        }
    }

This is the method where we interact with them. The crash happens on a cellForRow call for a cell that is out of view (aka dequeued)

  var firstFriendName: String = ""
        var numberOfFriends = 0
        if let selectedRow = recommendToFriendTableView.indexPathsForSelectedRows {
            numberOfFriends = selectedRow.count
            for i in 0..<selectedRow.count {
                let currentCell = recommendToFriendTableView.cellForRow(at: selectedRow[i]) as! RecommendToFriendsTableViewCell
                let friendID = currentCell.friendID
                idList.append(",\(friendID)")
            }
            let firstSelectedCell = recommendToFriendTableView.cellForRow(at: selectedRow[0]) as! RecommendToFriendsTableViewCell
            firstFriendName = firstSelectedCell.nameLabel.text!

After about a day of experimenting, I've yet to figure out the actual problem (other than the observation that it appears to be in regards to calling a dequeued cell)

Any help is appreciated.

Upvotes: 0

Views: 303

Answers (1)

Shehata Gamal
Shehata Gamal

Reputation: 100551

When this line

 let currentCell = recommendToFriendTableView.cellForRow(at: selectedRow[i]) as! RecommendToFriendsTableViewCell

crashes this means you access a non-visble cell so either use

 if let currentCell = recommendToFriendTableView.cellForRow(at: selectedRow[i]) as? RecommendToFriendsTableViewCell { }

or better use the dataSource array of the table to get the data that you want to gran wrongly from the cell

Upvotes: 2

Related Questions