0

I am trying to add 3 items too one tableview cell, right now its only printing the item from the first textfield three times like in the picture, i need it to print the first item, then second item and then the third item. I am confused on what i am doing wrong, the app completely crashes when i click the add button too.

Image Image

import UIKit
import SafariServices

class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate, UITextFieldDelegate {

    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var OrderNumberLabel: RoundedLabel2!
    @IBOutlet weak var CostLabel: RoundedLabel2!
    @IBOutlet weak var ProfitLabel: RoundedLabel2!
    @IBOutlet weak var TotalLabel: RoundedLabel2!

    @IBOutlet weak var itemTextField: UITextField!
    @IBOutlet weak var priceTextField: UITextField!
    @IBOutlet weak var saleTextField: UITextField!

        var items: [ItemRow] = []

        struct ItemRow
        {
          var first: String
          var second: String
          var third: String
        }

        override func viewDidLoad() {
            super.viewDidLoad()
//            tableView.tableFooterView = UIView(frame: CGRect.zero)
        }


    @IBAction func addButtonTapped(_ sender: Any) {
        insertNewItems()
    }



        func insertNewItems() {


            let newVideoRow = ItemRow(first: itemTextField.text!, second: priceTextField.text!, third: saleTextField.text!)
            items.append(newVideoRow)



            let indexPath = IndexPath(row: items.count - 1, section: 0)

            tableView.beginUpdates()
            tableView.insertRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()

            itemTextField.text = ""
            priceTextField.text = ""
            saleTextField.text = ""

            view.endEditing(true)
        }

    }





    extension ViewController: UITableViewDelegate, UITableViewDataSource {

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


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

             let ItemTitle = items[indexPath.row]

               let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell") as! ItemCell
               cell.itemLabel.text = ItemTitle.first
               cell.priceLabel.text = ItemTitle.second
               cell.saleLabel.text = ItemTitle.third
               return cell
        }


        func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
            return true
        }


        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

            if editingStyle == .delete {
                items.remove(at: indexPath.row)

                tableView.beginUpdates()
                tableView.deleteRows(at: [indexPath], with: .automatic)
                tableView.endUpdates()
            }
        }

1 Answers1

0

So my understanding is that you expect the following:-

  1. You start with an empty list.
  2. When the user presses the 'Add' button, the three entries are added to the list.
  3. The table below updates with three extra entries... or should it be one entry with the added three?

Let's take the first case, i.e. you want to add three rows. For this, you are correctly adding three rows to the videos array and the datasource extension is correct (although the usefulness of having three text fields with the same value is dubious). Your mistake is in the table update - you are telling it that one extra row is added with the lines:

let indexPath = IndexPath(row: videos.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

If you're adding three rows, you need to tell it that three rows are added, i.e.:-

let indexPath1 = IndexPath(row: videos.count - 3, section: 0)
let indexPath2 = IndexPath(row: videos.count - 2, section: 0)
let indexPath3 = IndexPath(row: videos.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath1, indexPath2, indexPath3], with: .automatic)
tableView.endUpdates()

If, on the other hand, you want only one row containing all three added, then your lines:-

videos.append(addVideoTextField.text!)
videos.append(addVideoTextField2.text!)
videos.append(addVideoTextField3.text!)

are incorrect. You will instead need to use a struct to contain the entries, and create a new instance and add that to videos. E.g. make a struct:-

struct VideoRow
{
  var first: String
  var second: String
  var third: String
}

Make this the data source, i.e. change your declaration to:-

var videos: [VideoRow] = []

Add add to that in the insert function:-

let newVideoRow = VideoRow(first: addVideoTextField.text!, second: addVideoTextField2.text!, third: addVideoTextField3.text!)
videos.append(newVideoRow)

Your cellForRowAt then becomes:

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

    let videoTitle = videos[indexPath.row]

    let cell = tableView.dequeueReusableCell(withIdentifier: "VideoCell") as! VideoCell
    cell.videoTitle.text = videoTitle.first
    cell.videoTitle2.text = videoTitle.second
    cell.videoTitle3.text = videoTitle.third
    return cell
}
Chris Shaw
  • 1,610
  • 2
  • 10
  • 14
  • Do you mean permanently as in through app launches/device power cycles? That's another question to ask separately, but the simplest way for you here would probably be via `UserDefaults`. – Chris Shaw Dec 11 '19 at 22:45
  • i updated the code, im getting " Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value " in cellForRowAt on the line that says "let cell =" –  Dec 11 '19 at 23:13
  • Well I didn't mean to change that line from your original. Have you just edited it, as I'm sure I just copied your existing code? – Chris Shaw Dec 11 '19 at 23:17
  • no i changed it, i just dont know how to save it with user defualts –  Dec 11 '19 at 23:18
  • Follow this question to start (https://stackoverflow.com/questions/28240848/how-to-save-an-array-of-objects-to-nsuserdefault-with-swift), ask a new question with any problems. – Chris Shaw Dec 11 '19 at 23:19