23

Embedded ViewControllers (Inácio Ferrarini)

Embed Size (px)

Citation preview

Page 1: Embedded ViewControllers  (Inácio Ferrarini)
Page 2: Embedded ViewControllers  (Inácio Ferrarini)

Embedded ViewControllers

Evitando Massive View Controllers

Page 3: Embedded ViewControllers  (Inácio Ferrarini)

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

Page 4: Embedded ViewControllers  (Inácio Ferrarini)

Este Talk

- Model, View e Controller- Embedding via Storyboard- Embedding via Código- Tópicos Adicionais

Page 5: Embedded ViewControllers  (Inácio Ferrarini)

Model, View e Controller

Model View

Controller

Notification&

KVOOutletDelegate

DataSourceTarget Action

Page 6: Embedded ViewControllers  (Inácio Ferrarini)

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.

Page 7: Embedded ViewControllers  (Inácio Ferrarini)

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() { } }

Page 8: Embedded ViewControllers  (Inácio Ferrarini)

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.

Page 9: Embedded ViewControllers  (Inácio Ferrarini)

Uso em Storyboards

Facilita o uso através de Container Views

Suporte a AutoLayout

Page 10: Embedded ViewControllers  (Inácio Ferrarini)

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 } } }

Page 11: Embedded ViewControllers  (Inácio Ferrarini)

Embedded Collection View

Um UITableView

Cada UITableViewCell contém um UICollectionView

Cada UICollectionView possui UICollectionViewCells

Page 12: Embedded ViewControllers  (Inácio Ferrarini)

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)

Page 13: Embedded ViewControllers  (Inácio Ferrarini)

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() } } }

Page 14: Embedded ViewControllers  (Inácio Ferrarini)

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() } } }

Page 15: Embedded ViewControllers  (Inácio Ferrarini)

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

Page 16: Embedded ViewControllers  (Inácio Ferrarini)

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 }

}

Page 17: Embedded ViewControllers  (Inácio Ferrarini)

Delegue para um Delegate Externo

class DemoTableViewDelegate: NSObject, UITableViewDelegate {

// MARK: - Properties let parentViewController: UIViewController // MARK: - Initialization init(parentViewController: UIViewController) { self.parentViewController = parentViewController }

// …

}

Page 18: Embedded ViewControllers  (Inácio Ferrarini)

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.

Page 19: Embedded ViewControllers  (Inácio Ferrarini)

Referências Externas

Yorkhttps://github.com/inacioferrarini/Yorkhttps://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/

Page 20: Embedded ViewControllers  (Inácio Ferrarini)

Contato

[email protected]@concrete.com.br

LinkedInhttps://br.linkedin.com/in/inacioferrarini

Gitghubhttps://github.com/inacioferrarini

iOS Dev BR@inacioferrarini

Page 21: Embedded ViewControllers  (Inácio Ferrarini)

Estamos Contratando!

Page 22: Embedded ViewControllers  (Inácio Ferrarini)

Dúvidas?

Page 23: Embedded ViewControllers  (Inácio Ferrarini)

www.concretesolutions.com.brblog.concretesolutions.com.br

Rio de Janeiro – Rua São José, 90 – cj. 2121Centro – (21) 2240-2030

São Paulo - Av. Nações Unidas, 11.541 3º andar - Brooklin - (11) 4119-0449