0

I have an array that I am trying to use to populate a tableview on a button press (nav bar button). I have used print statements to verify the proper data is present, but I am unable to get the table rows to display on the button press.

I assume the issue lies in my @IBAction func favoritesButton(_ sender: UIBarButtonItem) syntax, but now sure how. What am I missing?

class ViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!

    @IBOutlet weak var tableView: UITableView!

    var materialData = ["One", "Two", "Three", "Four", "Five"]

    override func viewDidLoad() {
        super.viewDidLoad()

        print(favoritesData)

    }

    @IBAction func arrayList(_ sender: UIBarButtonItem) {
        print(favoritesData)
    }

    @IBAction func favoritesButton(_ sender: UIBarButtonItem) {
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.numberOfLines = 0
            cell.textLabel?.text = favoritesData[indexPath.row]
            print(favoritesData)
            return cell
        }
    }
}

var searchMaterial = [String]()
var searching = false
var favoritesData = [String]()

extension ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        print(self.materialData[indexPath.row], "selected!")
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

        let favorite = UITableViewRowAction(style: .default, title: "Favorite") { (action, indexPath) in

            var data: String

            if searching {
                data = searchMaterial[indexPath.row]
                print(searchMaterial[indexPath.row], "added to favorites")
            } else {
                data = self.materialData[indexPath.row]
                print(self.materialData[indexPath.row], "added to favorites")
            }
            if let index = favoritesData.firstIndex(of: data) {
                favoritesData.remove(at: index)
            }
            else {
                favoritesData.append(data)
            }

        }
        favorite.backgroundColor = UIColor.orange
        return [favorite]
    }

}

extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searching {
            return searchMaterial.count
        } else {
            return materialData.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.numberOfLines = 0
        if searching {
            cell.textLabel?.text = searchMaterial[indexPath.row]
        } else {
            cell.textLabel?.text = materialData[indexPath.row]
        }
        return cell
    }

}

extension ViewController: UISearchBarDelegate {

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchBar.setShowsCancelButton(true, animated: true)
        searchMaterial = materialData.filter({$0.prefix(searchText.count) == searchText})
        searching = true
        tableView.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.setShowsCancelButton(false, animated: true)
        searching = false
        searchBar.text = ""
        tableView.reloadData()
        tableView.endEditing(true)
    }

}


1
  • What exactly are you trying to do when you push the favorite button? Commented May 12, 2020 at 20:08

1 Answer 1

1

Dont write cellForRow in button action .. cellForRowAtIndexPath is a method that your dataSource provides to the UITableView. It is called by iOS to load a cell for a specific indexPath. It works by dequeueing a reusable cell and filling in the information for that cell.

You typically do not call this. iOS does so

In your button action just set your DataSource like in your case set favoritesData like favoritesData = data and then call tableView.reloadData()

Sign up to request clarification or add additional context in comments.

15 Comments

how you assign data to your favoritesData variable ?
have you set your tableView delegate and dataSource ?
remove cellForRowAt from func favoritesButton
add another check in your main cell for row ... where you checking for searching or non searching
Create a variable isFavorite .. bool type ... enable it ... when you want to show fav data ... otherwise disable it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.