Skip to content

Commit

Permalink
Merge pull request #33 from AckeeCZ/improve_example
Browse files Browse the repository at this point in the history
Improve example
  • Loading branch information
janmisar authored Sep 19, 2018
2 parents 636bafb + 6e3ad5d commit 28c2fc9
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 32 deletions.
13 changes: 9 additions & 4 deletions ACKategories-Example/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import UIKit

@UIApplicationMain
final class AppDelegate: UIResponder, UIApplicationDelegate {

private lazy var appFlow = AppFlowCoordinator()

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
let window = UIWindow(frame: UIScreen.main.bounds)

self.window = window
self.window?.makeKeyAndVisible()

appFlow.start(in: window)

return true
}
}
41 changes: 41 additions & 0 deletions ACKategories-Example/Flow coordinators/AppFlowCoordinator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// AppFlowCoordinator.swift
// ACKategories-Example
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit
import ACKategories

final class AppFlowCoordinator: FlowCoordinator {
override func start(in window: UIWindow) {
super.start(in: window)

let exampleListVM = ExampleListViewModel()
let exampleListVC = ExampleListViewController(viewModel: exampleListVM)
exampleListVC.flowDelegate = self

let navigationController = UINavigationController(rootViewController: exampleListVC)
window.rootViewController = navigationController

self.rootViewController = navigationController
self.navigationController = navigationController
}
}

extension AppFlowCoordinator: ExampleListFlowDelegate {
func exampleItemSelected(_ item: ExampleItem, in viewController: ExampleListViewController) {
let itemVC = controller(for: item)
itemVC.title = item.title
navigationController?.pushViewController(itemVC, animated: true)
}

private func controller(for item: ExampleItem) -> UIViewController {
switch item {
case .uiControlBlocks: return UIControlBlocksViewController()
case .viewControllerComposition: return VCCompositionViewController()
}
}
}
26 changes: 26 additions & 0 deletions ACKategories-Example/Model/ExampleItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ExampleItem.swift
// ACKategories-Example
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import Foundation

enum ExampleItem {
case uiControlBlocks
case viewControllerComposition

static var allCases: [ExampleItem] { return [.uiControlBlocks, .viewControllerComposition] }

var title: String { return data.title }
var subtitle: String { return data.subtitle }

private var data: (title: String, subtitle: String) {
switch self {
case .uiControlBlocks: return ("UIControl blocks", "Use closures instead of target - selector pattern")
case .viewControllerComposition: return ("View controller composition", "Simply embed view controller into another one")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// ExampleListViewController.swift
// ACKategories-Example
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit

protocol ExampleListFlowDelegate: class {
func exampleItemSelected(_ item: ExampleItem, in viewController: ExampleListViewController)
}

final class ExampleListViewController: UIViewController {
weak var flowDelegate: ExampleListFlowDelegate?

private weak var tableView: UITableView!

private let viewModel: ExampleListViewModeling

// MARK: Initializers

init(viewModel: ExampleListViewModeling) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
self.title = "ACKategories"
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: View life cycle

override func loadView() {
super.loadView()

let tableView = UITableView()
view.addSubview(tableView)
tableView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
self.tableView = tableView
}

override func viewDidLoad() {
super.viewDidLoad()

tableView.delegate = self
tableView.dataSource = self
}

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

tableView.indexPathsForVisibleRows?.forEach { tableView.deselectRow(at: $0, animated: true) }
}
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = viewModel.items[indexPath.row]
let cell: TitleSubtitleTableViewCell = tableView.dequeueCell(for: indexPath)
cell.textLabel?.text = item.title
cell.detailTextLabel?.text = item.subtitle
return cell
}
}

extension ExampleListViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
flowDelegate?.exampleItemSelected(viewModel.items[indexPath.row], in: self)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// ExampleListViewModel.swift
// ACKategories
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

protocol ExampleListViewModelingActions {

}

protocol ExampleListViewModeling {
var actions: ExampleListViewModelingActions { get }

var items: [ExampleItem] { get }
}

extension ExampleListViewModeling where Self: ExampleListViewModelingActions {
var actions: ExampleListViewModelingActions { return self }
}

final class ExampleListViewModel: ExampleListViewModeling, ExampleListViewModelingActions {
let items = ExampleItem.allCases
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
//
// ViewController.swift
// ACKategories-Example
// UIControlBlocksViewController.swift
// ACKategories
//
// Created by Jakub Olejník on 06/02/2018.
// Copyright © 2018 Josef Dolezal. All rights reserved.
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit
import SnapKit
import ACKategories

final class ViewController: UIViewController {
final class UIControlBlocksViewController: UIViewController {

private weak var button: UIButton!

// MARK: View life cycle

override func loadView() {
super.loadView()

Expand All @@ -26,17 +26,6 @@ final class ViewController: UIViewController {
make.center.equalToSuperview()
}
self.button = button

let container = UIView()
view.addSubview(container)
container.snp.makeConstraints { (make) in
make.bottom.leading.trailing.equalToSuperview()
make.height.equalTo(100)
}

let childVC = UIViewController()
childVC.view.backgroundColor = .red
display(childViewController: childVC, in: container)
}

override func viewDidLoad() {
Expand All @@ -51,10 +40,4 @@ final class ViewController: UIViewController {
self.present(alertVC, animated: true)
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// TitleViewController.swift
// ACKategories
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit

class TitleViewController: UIViewController {
private(set) weak var nameLabel: UILabel!

private let name: String
private let color: UIColor

// MARK: Initializers

init(name: String, color: UIColor) {
self.name = name
self.color = color
super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: View life cycle

override func loadView() {
super.loadView()

view.backgroundColor = color

let nameLabel = UILabel()
nameLabel.textAlignment = .center
nameLabel.text = name
view.addSubview(nameLabel)
nameLabel.snp.makeConstraints { (make) in
make.leading.trailing.top.equalTo(safeArea).inset(20)
}
self.nameLabel = nameLabel
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// VCCompositionViewController.swift
// ACKategories
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit
import SnapKit

final class VCCompositionViewController: TitleViewController {

// MARK: Initializers

init() {
super.init(name: "Parent", color: .lightGray)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: View life cycle

override func loadView() {
super.loadView()

let containerView = UIView()
view.addSubview(containerView)
containerView.snp.makeConstraints { (make) in
make.leading.trailing.bottom.equalToSuperview()
make.top.equalTo(nameLabel.snp.bottom).offset(30)
}

let childVC = TitleViewController(name: "Child", color: .blue)
display(childViewController: childVC, in: containerView)
}
}
23 changes: 23 additions & 0 deletions ACKategories-Example/View/TitleSubtitleTableViewCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// TitleSubtitleTableViewCell.swift
// ACKategories-Example
//
// Created by Jakub Olejník on 12/09/2018.
// Copyright © 2018 Ackee, s.r.o. All rights reserved.
//

import UIKit

final class TitleSubtitleTableViewCell: UITableViewCell {

// MARK: Initializers

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}
Loading

0 comments on commit 28c2fc9

Please sign in to comment.