kriskrossy
kriskrossy

Reputation: 21

Change values in dictionary based on which cell selected in TableView

Storyboard

When clicking a cell from the tableView, the cells data (fetched from an array) gets passed on to the 'Detail View Controller' to be displayed in labels. When pressing edit on the Detailview, data gets passed to the 'Edit View Controller' textfields.

When editing those textfields and pressing "Save" I want this data to overwrite the current data in the arrays dictionary based on which cell that was pressed in the tableView.

What would be the best approach to this? Right now data gets passed all the way to the 'EditViewController', but not back to the corresponding dictionary in array when saved.

Main ViewController:

    class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { // Set up Delegate and Data Source for Table View

    @IBOutlet weak var tradeTableView: UITableView!
    
    var tradesList = TradeList()
    
    // Go to detail view of trade when pressing its tableview cell
    @IBSegueAction func showDetailView(_ coder: NSCoder) -> DetailViewController? {
        guard let indexPath = tradeTableView.indexPathForSelectedRow
        else { fatalError("Nothing selected!")}
        
        let trade = tradesList.trades[indexPath.row]
        
        return DetailViewController(coder: coder, trade: trade)
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the table view as the delegate and data source
        tradeTableView.dataSource = self
        tradeTableView.delegate = self
        
    }
    
    // Delegating functions for Table View
    func numberOfSections(in tableView: UITableView) -> Int {
        1
    }
    
    // Delegating functions for Table View
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        tradesList.trades.count
    }
    
    // Delegating functions for Table View
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "\(TradeCell.self)", for: indexPath) as? TradeCell
        else { fatalError("Could not create TradeCell")}
        
        let trade = tradesList.trades[indexPath.row]
        
        // Text to display in cells 'ticker' and 'name' label
        cell.tickerLabel?.text = trade.ticker
        cell.nameLabel?.text = trade.name
    
        return cell
    }
}

DetailViewController:

    class DetailViewController: UIViewController {
    
    let trade: Trade
    
    @IBOutlet var tickerLabel: UILabel!
    @IBOutlet var nameLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Changes labels according to which cell was pressed in ViewController
        tickerLabel.text = trade.ticker
        nameLabel.text = trade.name
    }
    
    // Initializers
    required init?(coder: NSCoder) { fatalError("This should never be called!")}
    
    required init?(coder: NSCoder, trade: Trade) {
        self.trade = trade
        super.init(coder: coder)
        
    }
    
    // Edit button tapped
    @IBAction func editTapped(_ sender: Any) {
        self.performSegue(withIdentifier: "DetailVCToEditVC", sender: self)
    }
    
    // Prepare data to pass to 'EditViewController'
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if(segue.identifier == "DetailVCToEditVC"){
            let displayVC = segue.destination as! EditViewController
            displayVC.editTitle = tickerLabel.text
            displayVC.editPrice = nameLabel.text
        }
    }
}

EditViewController:

class EditViewController: UIViewController {

// Variables recieving passed data from 'DetailViewController'
var editTitle: String?
var editPrice: String?

@IBOutlet weak var editTitleField: UITextField!
@IBOutlet weak var editPriceField: UITextField!


override func viewDidLoad() {
    super.viewDidLoad()
    // Setting the textfields text according to the passed data from 'DetailViewController'.
    editTitleField.text = editTitle
    editPriceField.text = editPrice
}

@IBAction func editSaveButton(_ sender: UIButton) {
    
    // Dismisses edit screen overlay
    self.dismiss(animated: true, completion: nil);
    
    }
}

My array is as follows in another swift file:

struct TradeList {
    
let trades: [Trade] = [
    Trade(ticker: "AAPL", name: "Apple"),
    Trade(ticker: "AMD", name: "Advanced Micro Devices")
]

}

Upvotes: 2

Views: 75

Answers (1)

abh
abh

Reputation: 1249

Use singleton pattern to update data. You don't need to pass data to view controllers. It will update automatically. Here is how your trade list struct should be

struct TradeList {
static let shared = TradeList(trades: [
    Trade(ticker: "AAPL", name: "Apple"),
    Trade(ticker: "AMD", name: "Advanced Micro Devices")
])

var trades: [Trade] = []

}

U can use it as following anywhere

for getting values

print(TradeList.shared.trades)

for updating values

TradeList.shared.trades = [...]//Any value here

Upvotes: 1

Related Questions