|
// HomeViewController.swift
// Paiai_iOS
// Created by FFIB on 16/3/28.
// Copyright © 2016年 FFIB. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
import PaiaiDataKit
import PaiaiUIKit
import PullToRefresh
final class HomeViewController: UIViewController {
@IBOutlet weak var scanBtn: UIButton!
@IBOutlet weak var createBtn: UIButton!
@IBOutlet weak var collectionView: UICollectionView!
// MARK: data property
fileprivate let disposeBag = DisposeBag()
internal var viewModel: HomeViewModel!
internal var userInfoViewModel: UserInfoViewModel!
override func viewDidLoad() {
super.viewDidLoad()
initalize()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func initalize() {
collectionView.register(UINib(nibName: "PhotoCell",
bundle: Bundle(identifier: "com.Paiai-iOS")),
forCellWithReuseIdentifier: "photoCell")
setup()
binding()
}
private func setup() {
setupReloadControl()
setupLoadingControl()
}
private func setupReloadControl() {
collectionView.addPullToRefresh(PullToRefresh()) {
[unowned self] in
self.viewModel.reload()
}
}
private func setupLoadingControl() {
collectionView.addPullToRefresh(PullToRefresh(position: .bottom)) {
[weak self] in
guard let `self` = self else { return }
self.viewModel.preload()
}
}
deinit {
collectionView.removeAllPullToRefresh()
}
}
/// UI bindings
fileprivate extension HomeViewController {
var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(
configureCell: {(_, collectionView, indexPath, item) -> UICollectionViewCell in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell",
for: indexPath) as! PhotoCell
cell.setInfo(item, source: .home)
return cell
})
}
func binding() {
bindInteraction()
bindViewModelToRefreshing()
bindCollectionViewDelegate()
bindUserInfoViewModelToView()
bindViewModelToCollectionView()
bindCollectionViewToViewModel()
}
func bindInteraction() {
createBtn.rx.tap.bind(to: viewModel.createBtnTapped).disposed(by: disposeBag)
scanBtn.rx.tap.bind(to: viewModel.scanBtnTapped).disposed(by: disposeBag)
}
func bindViewModelToRefreshing() {
viewModel.isLoading
.subscribe(onNext: {[unowned self] flag in
if flag {
self.collectionView.endRefreshing(at: .top)
} else {
self.collectionView.endRefreshing(at: .bottom)
}
}).disposed(by: disposeBag)
}
func bindCollectionViewDelegate() {
collectionView.rx.setDelegate(self).disposed(by: disposeBag)
}
func bindUserInfoViewModelToView() {
userInfoViewModel.isLoggedIn
.asDriver(onErrorJustReturn: ())
.drive(onNext: { (_) in
self.collectionView.startRefreshing(at: .top)
}).disposed(by: disposeBag)
}
func bindViewModelToCollectionView() {
viewModel.contents
.bind(to: collectionView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
func bindCollectionViewToViewModel() {
collectionView.rx.willDisplayCell
.asDriver()
.drive(onNext: { [unowned self] in self.preload(indexPath: $0.at) })
.disposed(by: disposeBag)
collectionView.rx.itemSelected
.asDriver(onErrorJustReturn: IndexPath(item: 0, section: 0))
.drive(onNext: { [unowned self] in self.viewModel.didSelect($0.row) })
.disposed(by: disposeBag)
}
func preload(indexPath: IndexPath) {
guard indexPath.row == collectionView.numberOfItems(inSection: 0) - 5 else { return }
collectionView.startRefreshing(at: .bottom)
}
}
extension HomeViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return viewModel.layoutSizeForIndexPath(indexPath)
}
}
extension HomeViewController: Storyboarded {
static func instantiate() -> HomeViewController {
return UIStoryboard.main.instantiateViewController(type: HomeViewController.self)
}
}
|