How to feed a tableView from a screen with information from another screen?

Asked

Viewed 223 times

0

Good evening, I have 3 screens in my app to buy passwords, the last of them has a Windows tablet powered by the passwords purchased by the user on a previous screen. He must choose a password and it should appear in his order summary on the next screen on a Windows tableView, if the user wants to buy another password, he can click on "next password" and return to the password screen and choose another to be added to the one previously chosen, but how to get the information added after choosing new passwords?

The flow goes like this:

Categories screen: User chooses which category and goes to password screen Password screen: User chooses password and goes to summary screen Summary screen: The tableView is fed with the chosen password and if the user wants to buy another one, back to the categories screen.

Class where passwords are chosen:

import UIKit

class ComprarSenhaViewController {

     static let sharedInstance = ComprarSenhaViewController()

     var senhasSelecionadas = Array<String>()
     var senhaAtual = Senha()

     @IBAction func fecharPedido(sender: AnyObject) {
        SenhaController.sharedInstance.senha = self.senhaAtual

        senhasSelecionadas.append("\(senhaAtual.id)")

        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let novoNavigation = storyBoard.instantiateViewControllerWithIdentifier("ResumoViewController")
        self.navigationController?.pushViewController(novoNavigation, animated: true)
    }
}

Class showing summary of chosen passwords:

import UIKit

class ResumoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{

    static let sharedInstance = ResumoViewController()

    var senhasSelecionadas = Array<String>()

    @IBOutlet weak var tableView: UITableView!

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

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

        let row = indexPath.row
        let idSenha = senhasSelecionadas[row]
        let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
        cell.textLabel!.text = idSenha
        return cell
    }

    func carregarResumoSenhas(){

        ComprarSenhaViewController.sharedInstance.senhasSelecionadas = self.senhasSelecionadas
        let idsenha = SenhaController.sharedInstance.senha.id
        senhasSelecionadas.append("\(idsenha)")

        tableView.reloadData()

    }
    @IBAction func proximaSenha(sender: AnyObject) {        
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let novoNavigation = storyBoard.instantiateViewControllerWithIdentifier("CategoriaViewController")
        self.navigationController?.pushViewController(novoNavigation, animated: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        carregarResumoSenhas()

    }
  • You are wearing delegate? Delegation is a design Pattern that Enables a class or Structure to hand off (or delegate) some of its responsibilities to an instance of Another type.

2 answers

3

Using protocol, as mentioned, you can do this as follows: the protocol definition will be in your class ResumoViewController, this one I’ll call ResumoDelegate.

In this protocol I will define a method that will return all purchased passwords, and so on viewWillAppear searches that list and updates the summary table.

protocol ResumoDelegate {
    func listaSenhas() -> [Senha]
}

class ResumoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var delegate: ResumoDelegate?
    var senhasSelecionadas: [Senha] = []

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        senhasSelecionadas = delegate?.listaSenhas()

        tableView.reloadData()
    }
}

Now, the implementation of this method is on your screen ComprarSenhaViewController:

class ComprarSenhaViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, ResumoDelegate {
    var senhasSelecionadas: [Senha] = []

    @IBAction func fecharPedido(sender: AnyObject) {
        senhasSelecionadas.append(senhaAtual)

        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let resumoController = storyBoard.instantiateViewControllerWithIdentifier("ResumoViewController")
        resumoController.delegate = self

        self.navigationController?.pushViewController(resumoController, animated: true)
    }

    func listaSenhas() -> [Senha] {
        return senhasSelecionadas
    }
}

Note that you also need to include ResumoDelegate in the class signature and before the pushViewController define the delegate as the class itself.

  • I tried to use delegate, but it didn’t work, I used sharedInstance to share the information from one screen to another and I got it. : ) Thanks.

0


Do not use Delegate because you will be creating an unnecessary dependency. senhasSelecionadas is a public variable and ComprarSenhaViewController has a reference to ResumoViewController, then just assign a value to senhasSelecionadas just before the pushViewController.

...
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let resumoController = storyBoard.instantiateViewControllerWithIdentifier("ResumoViewController")
resumoController.senhasSelecionadas = senhasSelecionadas
self.navigationController?.pushViewController(resumoController, animated: true)
...

I also don’t understand why you’re using Singleton in your ViewControllers.

  • Alice, if you are using Singleton to share information between Viewcontrollers (VC’s) then this is not the best way to do it. Suppose Voce has two VC’s in which one calls the other. VC1 -> VC2. Then expose a property in VC2 (make it public) so that VC1 can assign it before calling the push or in prepareForSegue (if using storyboard). If Voce needs to update VC1 with some VC2 information or simply notify any changes then use delegate and Protocol. If the VC’s do not have a direct relationship think about using Notifications or KVO.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.