0

When I call the tableView function I get the error in the title. My question is why won't the function take the two arguments even though they are of the requested type? Again I'm a newbie so please forgive me if the answer is obvious.

class TableViewController: UITableViewController { 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell { 
        let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! UITableViewCell 
        let name = Array(shopItems.keys) [indexPath.row]
        let cost = Array(shopItems.values) [indexPath.row] 
        cell.textLabel?.text = name + String(cost)
        return cell 
    }
}

When I call the function like this:

"TableViewController.tableView(shopTableView, IndexPath: NSIndexPath)" I get the error: "Argument labels '(_:, IndexPath:)' do not match any available overloads"

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
Rich
  • 1
  • 1
  • Why are you calling this method in the first place? You shouldn't call this method. You should write this method, and let the framework call it. – Sweeper Sep 04 '19 at 14:05
  • I want it to be called when the user presses a button, so that a cell is added every time the user taps it – Rich Sep 04 '19 at 14:13
  • That's not how you add new cells to a table view. See [this](https://stackoverflow.com/questions/31870206/how-to-insert-new-cell-into-uitableview-in-swift). – Sweeper Sep 04 '19 at 14:14
  • If I run my app with adjusted code provided in that post I get this error: "attempt to insert row 0 into section 1, but there are only 1 sections after the update" – Rich Sep 04 '19 at 14:25

2 Answers2

0

Try use

 let name = shopItems.keys[indexPath.row]

Instead of

    let name = Array(shopItems.keys) [indexPath.row]

Better don't use force wrap, when it's not nesesery. Try change

let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! UITableViewCell

to

 guard let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as? UITableViewCell else { 
    return UITableViewCell()
}

EDIT: As @Sh_Khan say replace

func tableView(_ tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell {

to

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
JamesVoo
  • 145
  • 1
  • 11
  • When I change the name and cost constants I get this error: "Cannot subscript a value of type 'Dictionary.Keys' with an index of type 'Int'". And I also still get my original error – Rich Sep 04 '19 at 13:54
  • I didn't know it was a dictionary. In that case, restore the version you had – JamesVoo Sep 04 '19 at 13:59
  • Yeah, sorry I should've mentioned that. Basically I have a dictionary that takes a string and an Integer and this function is supposed to create a table View cell with the String and Integer as its label – Rich Sep 04 '19 at 14:02
  • *Better don't use force wrap*. No, in this case force unwrapping is welcome because the code **must not** crash if everything is hooked up correctly. If it does it reveals a **design** mistake. Optional Binding displays nothing in case of the mentioned design mistake and you have no idea why. The bad user experience is the same in both ways. – vadian Sep 04 '19 at 16:37
  • @vadian - to better user experience You can show pop up with information about error and dismiss view. It's better than crash – JamesVoo Sep 04 '19 at 16:39
  • Runtime checks for errors which can be resolved at compile/design time is unnecessarily expensive. There are only a few rare cases where force unwrapping is perfectly fine. This is one of them. – vadian Sep 04 '19 at 16:43
0

There is an easy and quick way to figure out yourself the proper overload

  1. Select the entire method and press ⌘/ to comment out the code.
  2. On the top level of the class type cellForRow. The first item in the code completion list is the proper method.
  3. Press Return to insert the correct method.
  4. Comment in the wrong method by selecting it again and pressing ⌘/.
  5. Copy and paste the body of the wrong method into the correct one.
  6. Delete the rest of the wrong method.
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you, I still cannot get it work though. Sweeper mentioned that I shouldn't call the method but I don't get why. Don't I have to provide the function with a Table View on which to perform the method? – Rich Sep 06 '19 at 12:05
  • Sweeper is right. You must not call the method yourself. The method is called by the framework right after you called `tableView.reloadData()`. But you have to override also `numberOfRowsInSection` to return the number of rows you want to display. – vadian Sep 06 '19 at 12:07