Reputation: 242
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)
}
}
Upvotes: 0
Views: 567
Reputation: 14397
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()
Upvotes: 1