Skip to content

Commit

Permalink
Added home states
Browse files Browse the repository at this point in the history
  • Loading branch information
frankfka committed May 31, 2019
1 parent 0d2feb7 commit d991060
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 40 deletions.
8 changes: 8 additions & 0 deletions SimpleScanner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
9E04B2B124FBCD83AC383B9F /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BF36B80CD96B067CC262 /* Text.swift */; };
9E04B3D8FB6196F3A7040BB1 /* AppStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B94C89CFCEB2536DAF75 /* AppStore.swift */; };
9E04B43A3E35CAAE6AA0188D /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B0FD31D5EBEE2548788A /* AppState.swift */; };
9E04B4702EC2958221A1B946 /* HomeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B8175178719E51E94022 /* HomeAction.swift */; };
9E04B63EC45E8A9CDB7EA576 /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BE3B98EE1903F8109383 /* HomeViewModel.swift */; };
9E04B6CCC1F5BB2142CC81C3 /* NewScanController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B3CBA9AD2F2805B61AA8 /* NewScanController.swift */; };
9E04B7379326CC3F426DEC11 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B33BC071885CC1FC11FC /* View.swift */; };
9E04B7BD98B7D676C19371B6 /* NewScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BC479B0A06D4C7085624 /* NewScanView.swift */; };
9E04B87E33C1BFE1D2CCEC89 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04B2D900256F50CB23B4D8 /* HomeView.swift */; };
9E04BB22843A1193CEE08A9A /* TextButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BF9490C73C86266D98EF /* TextButton.swift */; };
9E04BC526BBA4D17234DBD8E /* HomeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BD62F1EF9A07F421A937 /* HomeController.swift */; };
9E04BC8228E151697531252F /* HomeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BA706303AC9C17924E81 /* HomeState.swift */; };
9E04BFB9572504855D8AF039 /* TypeAlias.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04BB0CB53C787C4A107133 /* TypeAlias.swift */; };
/* End PBXBuildFile section */

Expand All @@ -38,7 +40,9 @@
9E04B33BC071885CC1FC11FC /* View.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
9E04B34FB0867314FA274D65 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
9E04B3CBA9AD2F2805B61AA8 /* NewScanController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewScanController.swift; sourceTree = "<group>"; };
9E04B8175178719E51E94022 /* HomeAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeAction.swift; sourceTree = "<group>"; };
9E04B94C89CFCEB2536DAF75 /* AppStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppStore.swift; sourceTree = "<group>"; };
9E04BA706303AC9C17924E81 /* HomeState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeState.swift; sourceTree = "<group>"; };
9E04BB0CB53C787C4A107133 /* TypeAlias.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = "<group>"; };
9E04BC479B0A06D4C7085624 /* NewScanView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewScanView.swift; sourceTree = "<group>"; };
9E04BD62F1EF9A07F421A937 /* HomeController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -115,6 +119,7 @@
9E04B79B62B5E69A5E4CBED1 /* Action */ = {
isa = PBXGroup;
children = (
9E04B8175178719E51E94022 /* HomeAction.swift */,
);
path = Action;
sourceTree = "<group>";
Expand Down Expand Up @@ -169,6 +174,7 @@
9E04BE6EC52B11F39F8362CD /* State */ = {
isa = PBXGroup;
children = (
9E04BA706303AC9C17924E81 /* HomeState.swift */,
);
path = State;
sourceTree = "<group>";
Expand Down Expand Up @@ -317,6 +323,8 @@
9E04B6CCC1F5BB2142CC81C3 /* NewScanController.swift in Sources */,
9E04B7BD98B7D676C19371B6 /* NewScanView.swift in Sources */,
9E04B63EC45E8A9CDB7EA576 /* HomeViewModel.swift in Sources */,
9E04BC8228E151697531252F /* HomeState.swift in Sources */,
9E04B4702EC2958221A1B946 /* HomeAction.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
3 changes: 2 additions & 1 deletion SimpleScanner/Common/TypeAlias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@

import Foundation

public typealias VoidCallback = () -> ()
public typealias VoidCallback = () -> ()
public typealias TapIndexCallback = (Int) -> ()
14 changes: 6 additions & 8 deletions SimpleScanner/Constant/View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ class View {
// Collection View
static let CollectionViewItemsPerRow: CGFloat = 2
static let CollectionViewSectionInsets = UIEdgeInsets(top: SectionVerticalMargin, left: ViewPadding, bottom: SectionVerticalMargin, right: ViewPadding)
static let CollectionViewSize: CGSize = {
get {
let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
let availableWidth = view.frame.width - paddingSpace
let widthPerItem = availableWidth / itemsPerRow

return CGSize(width: widthPerItem, height: widthPerItem)
}
static func CollectionViewSize(frameWidth: CGFloat) -> CGSize {
let paddingSpace = CollectionViewSectionInsets.left * (CollectionViewItemsPerRow + 1)
let availableWidth = frameWidth - paddingSpace
let widthPerItem = availableWidth / CollectionViewItemsPerRow
return CGSize(width: widthPerItem, height: widthPerItem)
}
static let DocumentCollectionCellReuseID: String = "DocumentCell"

}
16 changes: 16 additions & 0 deletions SimpleScanner/Redux/Action/HomeAction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Created by Frank Jia on 2019-05-30.
// Copyright (c) 2019 Frank Jia. All rights reserved.
//

import Foundation
import ReSwift

// Add document tapped on home screen
struct AddNewDocumentTappedAction: Action { }
// Called when anything is presented/pushed onto Home screen
struct DidNavigateAwayAction: Action { }
// When document tapped in UICollectionView
struct DocumentTappedAction: Action {
let index: Int
}
6 changes: 4 additions & 2 deletions SimpleScanner/Redux/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import ReSwift

public struct AppState: StateType {

func reduce(action: Action, state: AppState?) -> AppState {
return AppState(
let homeState: HomeState

func reduce(action: Action, state: AppState) -> AppState {
return AppState(
homeState: homeState.reduce(action: action, state: state.homeState)
)
}
}
2 changes: 1 addition & 1 deletion SimpleScanner/Redux/AppStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public let appStore = AppStore(reducer: appReducer, state: nil)
func appReducer(action: Action, state: AppState?) -> AppState {
// Default state if state does not exist
let state = state ?? AppState(

homeState: HomeState()
)
return state.reduce(action: action, state: state)
}
44 changes: 44 additions & 0 deletions SimpleScanner/Redux/State/HomeState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Created by Frank Jia on 2019-05-30.
// Copyright (c) 2019 Frank Jia. All rights reserved.
//

import ReSwift

struct HomeState {

let documents: [String]

// Navigation
let showAddDocument: Bool
let showDocumentWithIndex: Int?

init(
documents: [String] = ["First", "Second"],
showAddDocument: Bool = false,
showDocumentWithIndex: Int? = nil
) {
self.documents = documents
self.showAddDocument = showAddDocument
self.showDocumentWithIndex = showDocumentWithIndex
}

func reduce(action: Action, state: HomeState) -> HomeState {
switch action {
case _ as AddNewDocumentTappedAction:
return HomeState(showAddDocument: true)
case let action as DocumentTappedAction:
return HomeState(showDocumentWithIndex: action.index)
case _ as DidNavigateAwayAction:
return didNavigateAway()
default:
return self
}
}

// Reset all navigation states
private func didNavigateAway() -> HomeState {
return HomeState(showAddDocument: false, showDocumentWithIndex: nil)
}

}
53 changes: 50 additions & 3 deletions SimpleScanner/Screen/Home/HomeController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import UIKit
import SnapKit
import ReSwift

class HomeController: UIViewController {

Expand All @@ -25,18 +26,64 @@ class HomeController: UIViewController {

override func loadView() {
self.title = Text.HomeViewTitle
homeView = HomeView(viewModel: HomeViewModel(test: ["Item 1", "Item 2"]), newScanTapped: newScanTapped)
homeView = HomeView(
viewModel: HomeViewModel(state: store.state.homeState),
newScanTapped: newScanTapped,
itemTapped: itemTapped
)
self.view = homeView
}

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
store.subscribe(self) {
$0.select {
$0.homeState
}
}
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
store.unsubscribe(self)
}

private func newScanTapped() {
navigationController?.pushViewController(NewScanController(), animated: true)
store.dispatch(AddNewDocumentTappedAction())
}

private func itemTapped(index: Int) {
store.dispatch(DocumentTappedAction(index: index))
}

}

// Redux Extension
extension HomeController: StoreSubscriber {

public func newState(state: HomeState) {

// Present new scan screen if state calls for it
if state.showAddDocument {
self.present(UINavigationController(rootViewController: NewScanController(store: appStore)), animated: true) { [weak self] in
self?.store.dispatch(DidNavigateAwayAction())
}
}

// Present PDF if state calls for it
if let docIndex = state.showDocumentWithIndex {
self.store.dispatch(DidNavigateAwayAction())
}

// Update Views
homeView.update(viewModel: HomeViewModel(state: state))

}

}


53 changes: 31 additions & 22 deletions SimpleScanner/Screen/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ class HomeView: UIView {

// Callbacks
private let newScanTapped: VoidCallback
private let itemTapped: TapIndexCallback


init(viewModel: HomeViewModel, newScanTapped: @escaping VoidCallback) {
init(viewModel: HomeViewModel, newScanTapped: @escaping VoidCallback, itemTapped: @escaping TapIndexCallback) {
self.vm = viewModel
self.newScanTapped = newScanTapped
self.itemTapped = itemTapped
super.init(frame: CGRect.zero)
initSubviews()
}
Expand All @@ -30,6 +31,33 @@ class HomeView: UIView {
fatalError("init(coder:) has not been implemented")
}

func update(viewModel: HomeViewModel) {
self.vm = viewModel
// Do other updating here
}

}

// UICollectionView Delegate
extension HomeView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return vm.documents.count
}

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return View.CollectionViewSize(frameWidth: collectionView.frame.width)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: View.DocumentCollectionCellReuseID, for: indexPath)
myCell.backgroundColor = UIColor.blue
return myCell
}

public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.itemTapped(indexPath.row)
}
}

// Initialization
Expand Down Expand Up @@ -72,32 +100,13 @@ extension HomeView {
documentCollectionView.backgroundColor = Color.BodyBackground
documentCollectionView.delegate = self
documentCollectionView.dataSource = self
documentCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
documentCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: View.DocumentCollectionCellReuseID)
addSubview(documentCollectionView)
documentCollectionView.snp.makeConstraints { (make) in
make.right.equalToSuperview()
make.left.equalToSuperview()
make.bottom.equalTo(bottomBar.snp.top)
make.top.equalToSuperview()
}
flowLayout.itemSize = View.CollectionItemSize
}
}

// UICollectionView Delegate
extension HomeView: UICollectionViewDelegate, UICollectionViewDataSource {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return vm.test.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
myCell.backgroundColor = UIColor.blue
return myCell
}

public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Tap at \(indexPath.row)")
}
}
6 changes: 3 additions & 3 deletions SimpleScanner/Screen/Home/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import UIKit

class HomeViewModel {

let test: [String]
let documents: [String]

init(test: [String]) {
self.test = test
init(state: HomeState) {
self.documents = state.documents
}

}

0 comments on commit d991060

Please sign in to comment.