1

I am trying out an exercise in creating a simple todo list. Before introducing Realm or coreData i wanted to test it out and see if everyting is going smoothly.

I know i probably can make this work with some if conditions but i would love to be able to use the nil coalescing operator (i just love the simplicity of it), and i am not sure why its not working.

I made it work without it, but really interested what is the reason it is behaving like this.

When i launch the app it just shows "No Category Added" even after i add some items to the array and print them out, list stays the same.

import UIKit

class CategoriesTableView: UITableViewController {

  var testData = [FauxData]()

  override func viewDidLoad() {

    super.viewDidLoad()
    tableView.reloadData()

  }

  // MARK: - Data Methods

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    let data = testData[indexPath.row].categoryTitle ?? "No Category Added"
    cell.textLabel?.text = data

    return cell
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return testData.count
  }

  @IBAction func addItem(_ sender: UIBarButtonItem) {
  CreateNewItem(item: "test")
  tableView.reloadData()
  }

  func CreateNewItem(item: String) {
    let newItem = FauxData()
    newItem.categoryTitle = item
    testData.append(newItem)
    print(item)
  }

}

This is the class FauxData:

class FauxData {
  var categoryTitle: String?
}

Sry if this is too simple or a duplicate, i wasn't able to find and appropriate answer.

emin
  • 289
  • 1
  • 10
  • 1
    When you launch the app you should see no rows in the table. You need to tap your "add" button to see the text item. – rmaddy May 14 '18 at 21:06
  • But when there are no items in the array i want the text "No Category Added", and once data is entered then that text is replaced with the data. – emin May 14 '18 at 21:33
  • To be clear, the code you posted will show the correct data when there is data and it will show nothing when there is no data. So the only change you need is to show one row when there is no data. Is this correct? – rmaddy May 14 '18 at 21:50
  • Exactly that :) – emin May 15 '18 at 02:17

1 Answers1

1

Unfortunately, indexing an empty array crashes instead of returning nil, so you can't use the nil coalescing operator. Instead, use the .isEmpty property along with the ?: operator to achieve your goal:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    let data = testData.isEmpty ? "No Category Added" : testData[indexPath.row].categoryTitle
    cell.textLabel?.text = data

    return cell
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return testData.isEmpty ? 1 : testData.count
}

Note: You have to return 1 from tableView(_:numberOfRowsInSection:) when the array is empty so that tableView(_:cellForRowAt:) will be called to return your default message.


If you implement safe array indexing, you could then use the nil coalescing operator:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    let data = testData[safe: indexPath.row]?.categoryTitle ?? "No Category Added"
    cell.textLabel?.text = data

    return cell
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return testData.isEmpty ? 1 : testData.count
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • Not only it works like a charm, it is still very clean and nice code! Thank you! Tnx for the second solution as well, i LOVE safe array indexing, never saw that before! It looks so simple and interesting. p.s. i actually could not sleep trying to think why its not working properly, and i got up at 3.50AM just to see you posted the answer around that time :) – emin May 15 '18 at 02:36