Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Embedded View Controllers - Evitando Massive View Controllers

Embedded View Controllers - Evitando Massive View Controllers

Talk sobre como utilizar Embedded View Controllers para tornar View Controllers menores.

Apresentação originalmente feita no CocoaHeads, São Paulo, 25 de outubro de 2016.

Inácio Ferrarini

October 25, 2016
Tweet

More Decks by Inácio Ferrarini

Other Decks in Programming

Transcript

  1. Inácio Ferrarini - https://github.com/inacioferrarini - Programador Java desde 2004 -

    Programador iOS desde 2014 - Graduado em Sistemas de Informação pela FRB (2008) - Pós-Graduado em Desenvolvimento de Aplicativos e Games para Dispositivos Móveis pela FIAP (2015) - Contribuinte Open Source - Autor do POD York
  2. Este Talk - Model, View e Controller - Embedding via

    Storyboard - Embedding via Código - Tópicos Adicionais
  3. Model, View e Controller Model View Controller Notification & KVO

    O utlet D elegate D ataSource Target A ction
  4. Model, View e Controller (cont.) Ao mesmo tempo em que

    View e Model possuem papéis bem definidos, não podemos dizer o mesmo do Controller. Por uma falha comum de entendimento, assume-se que MVC seja apenas Model, View e Controller. Entretanto, Model, View e Controller são os 3 tipos de objetos mais frequentes. Objetos de apoio devem ser criados sempre que necessário.
  5. Exemplos Uma UITableViewCell responsável por lidar com uma target action

    - @IBAction - é uma “ViewViewController”. class UITableViewCellViewControllerTableViewCell: UITableViewCell { @IBOutlet weak var button: UIView! @IBAction func buttonAction() { } }
  6. Exemplos UITableViewController UICollectionViewController UITableViewCells UICollectionViewDelegate UICollectionViewDataSource Ao "embeddar" um UICollectionView

    em uma UITableViewCell, o ideal é que o DataSource e Delegate não fiquem no ViewController “raiz”. Desta forma, cada ViewController é responsável pelo Delegate e DataSource que use. Neste caso, o UITableViewCell deve importar um UICollectionViewController ou similar.
  7. Uso em Storyboards (cont.) Utiliza a mecânica de segues ao

    carregar suas Embedded ViewControllers class BaseViewController: UIViewController { var tableViewController: TableViewController? override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let vc = segue.destinationViewController as? TableViewController { self.tableViewController = vc } } }
  8. Embedded Collection View (cont.) UITableViewDelegate possui dois métodos importantes: func

    tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
  9. Embedded Collection View (cont.) Estes métodos são chamados, respectivamente, quando

    o UITableViewController estiver prestes a exibir e a deixar de exibir a UITableViewCell em questão. class DemoTableViewDataSource: NSObject, UITableViewDataSource { // MARK: - Embedded func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if let cell = cell as? EmbededViewControllerTableViewCell { cell.embedInParentViewController(self.parentViewController) } } func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if let cell = cell as? EmbededViewControllerTableViewCell { cell.unEmbedFromParentViewController() } } }
  10. TableViewCell: Embedding with Code class EmbededViewControllerTableViewCell: UITableViewCell { // MARK:

    - Properties var embeddedViewController: UIViewController? // MARK : - Embedding func embedInParentViewController(parentViewController: UIViewController) { if let embeddedViewController = self.embeddedViewController { parentViewController.addChildViewController(embeddedViewController) embeddedViewController.didMoveToParentViewController(parentViewController) self.contentView.addSubview(embeddedViewController.view) } } func unEmbedFromParentViewController() { if let embeddedViewController = self.embeddedViewController { embeddedViewController.view.removeFromSuperview() embeddedViewController.willMoveToParentViewController(nil) embeddedViewController.removeFromParentViewController() } } }
  11. Tópicos Adicionais - Massive View Controller O principal benefício que

    um Embedded ViewController provê é uma melhor organização e estruturação Possibilita compor um ViewController a partir de ViewControllers menores; ViewControllers podem ficar menores e mais específicos Funcionalidades auxiliares (ex: Uma View com campo de texto que faz busca através de uma API) se tornam candidatos a Reúso Para não gerar acoplamento, clojures ou notifications devem ser utilizados
  12. Delegue para um DataSource Externo class DemoTableViewDataSource: NSObject, UITableViewDataSource {

    // MARK: - Properties let parentViewController: UIViewController // MARK: - Initialization init(parentViewController: UIViewController) { self.parentViewController = parentViewController } // MARK: - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.viewControllers.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("EmbededViewControllerTableViewCell", forIndexPath: indexPath) if let cell = cell as? EmbededViewControllerTableViewCell where indexPath.row < self.viewControllers.count { cell.embeddedViewController = viewControllers[indexPath.row] } return cell } }
  13. Delegue para um Delegate Externo class DemoTableViewDelegate: NSObject, UITableViewDelegate {

    // MARK: - Properties let parentViewController: UIViewController // MARK: - Initialization init(parentViewController: UIViewController) { self.parentViewController = parentViewController } // … }
  14. Resumo Embedded ViewControllers possibilitam ViewControllers mais específicos e reutilizáveis É

    uma forma de evitar o Massive ViewController – Por sua vez, é um tópico vasto e recorrente – Geralmente causado por erosão arquitetural – Existem diversas alternativas, muitas delas são outras arquiteturas, como V.I.P.E.R.
  15. Referências Externas York https://github.com/inacioferrarini/York https://cocoapods.org/pods/York "Creating a Scrolling Filmstrip Within

    a UITableView” http://devblog.orgsync.com/2013/04/26/ creating_scrolling_filmstrip_within_uitableview/ "View Controllers in Cells” http://khanlou.com/2015/04/view-controllers-in-cells/
  16. www.concretesolutions.com.br blog.concretesolutions.com.br Rio de Janeiro – Rua São José, 90

    – cj. 2121 Centro – (21) 2240-2030 São Paulo - Av. Nações Unidas, 11.541
 3º andar - Brooklin - (11) 4119-0449