|
//
// GroupViewController.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 PaiaiUIKit
import PaiaiDataKit
import PullToRefresh
final class GroupViewController: UIViewController {
// MARK: Storyboard property
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var photographBtn: UIButton!
@IBOutlet weak var emptyView: UIStackView!
@IBOutlet weak var qrImageView: UIImageView!
// MARK: custom UI property
var navigationBarView: UIView = {
let view = UIView()
view.alpha = 0
return view
}()
var navigationBarViewTitle: UILabel = {
let label = UILabel()
label.textColor = UIColor.white
return label
}()
var navigationBarViewImage: UIImageView = {
let image = UIImageView()
image.cornerRadius = 18
return image
}()
// MARK: data property
var viewModel: GroupViewModel!
fileprivate var navigationViewNotReady = true
fileprivate let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
initalize()
navigationController?.navigationBar.setBackgroundImage(UIImage.Navigation.background, for: .default)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
func initalize() {
collectionView.register(UINib(nibName: "PhotoCell",
bundle: Bundle(identifier: "com.Paiai-iOS")),
forCellWithReuseIdentifier: "photoCell")
collectionView.alwaysBounceVertical = true
setup()
binding()
setupNavigationBar()
}
private func setup() {
setupReloadControl()
}
private func setupReloadControl() {
collectionView.addPullToRefresh(PullToRefresh()) {
[weak self] in
guard let `self` = self else { return }
self.viewModel.reload()
}
collectionView.startRefreshing(at: .top)
}
override func removeFromParent() {
super.removeFromParent()
print(self)
}
deinit {
collectionView.removeAllPullToRefresh()
}
}
/// UI bindings
fileprivate extension GroupViewController {
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: .group)
return cell
})
}
func binding() {
bindViewModelToEmptyView()
bindViewModelToQRImageView()
bindViewModelToRefreshing()
bindCollectionViewDelegate()
bindViewModelToCollectionView()
bindCollectionViewToViewModel()
bindViewModelToNavigationBarImage()
bindViewModelToNavigationBarTitle()
}
func bindViewModelToEmptyView() {
viewModel.hasData.bind(to: emptyView.rx.isHidden).disposed(by: disposeBag)
}
func bindViewModelToQRImageView() {
viewModel.groupItem
.map { UIImage(qr: "https:api.pai.ai/g/\($0.group_id)") }
.bind(to: qrImageView.rx.image)
.disposed(by: disposeBag)
}
func bindViewModelToRefreshing() {
viewModel.isLoading
.subscribe(onNext: {[unowned self] _ in
self.collectionView.endRefreshing(at: .top)
}).disposed(by: disposeBag)
}
func bindCollectionViewDelegate() {
collectionView.rx.setDelegate(self).disposed(by: disposeBag)
}
func bindViewModelToCollectionView() {
viewModel.contents
.bind(to: collectionView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
func bindCollectionViewToViewModel() {
collectionView.rx.itemSelected
.asDriver()
.drive(onNext: { [unowned self] in self.viewModel.didSelect($0.item) })
.disposed(by: disposeBag)
}
func bindViewModelToNavigationBarTitle() {
viewModel.group_name.bind(to: navigationBarViewTitle.rx.text).disposed(by: disposeBag)
}
func bindViewModelToNavigationBarImage() {
viewModel.group_avatar
.subscribe(onNext: {[weak self] (avatar) in
guard let `self` = self else { return }
self.navigationBarViewImage.image = UIImage(named: avatar)
}).disposed(by: disposeBag)
}
}
extension GroupViewController {
func setupNavigationBar() {
guard navigationViewNotReady else { return }
setRightBarButtonItems()
constructNaivgationViewHierarchy()
activateConstraintsNavigation()
navigationViewNotReady = false
}
private func constructNaivgationViewHierarchy() {
navigationItem.titleView = navigationBarView
navigationBarView.addSubview(navigationBarViewImage)
navigationBarView.addSubview(navigationBarViewTitle)
}
private func setRightBarButtonItems() {
let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
UIImage(named: "navigation-right")],
targets: [self, viewModel!],
actions: [#selector(GroupViewController.presentGroupQR),
#selector(GroupViewModel.navigateToGroupDetail)])
navigationItem.setRightItem(item)
}
@objc func presentGroupQR() {
let groupItem = viewModel.groupItem.value
let qrView = GroupQRView(group_name: groupItem.group_name,
group_avatar: "Group\(groupItem.group_default_avatar)",
groupQR: "https:api.pai.ai/g/\(groupItem.group_id)")
let alert = AlertViewController(style: .custom(qrView, AlertAnimator()))
presentController(alert)
}
}
/// navigation bar layout
fileprivate extension GroupViewController {
func activateConstraintsNavigation() {
activateConstraintsNavigationBarViewImage()
activateConstraintsNavigationBarViewTitle()
if #available(iOS 11, *) { return }
navigationBarViewTitle.sizeToFit()
navigationBarView.frame.size = CGSize(width: navigationBarViewTitle.bounds.size.width + 42, height: 36)
}
func activateConstraintsNavigationBarViewTitle() {
navigationBarViewTitle.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
navigationBarViewTitle.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
navigationBarViewTitle.widthAnchor.constraint(lessThanOrEqualToConstant: view.width - 200),
navigationBarViewTitle.trailingAnchor.constraint(equalTo: navigationBarView.trailingAnchor),
navigationBarViewTitle.leadingAnchor.constraint(equalTo: navigationBarViewImage.trailingAnchor, constant: 6)
])
}
func activateConstraintsNavigationBarViewImage() {
navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
navigationBarViewImage.widthAnchor.constraint(equalToConstant: 36),
navigationBarViewImage.heightAnchor.constraint(equalToConstant: 36),
navigationBarViewImage.topAnchor.constraint(equalTo: navigationBarView.topAnchor),
navigationBarViewImage.bottomAnchor.constraint(equalTo: navigationBarView.bottomAnchor),
navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor)
])
}
}
extension GroupViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return viewModel.layoutSizeForIndexPath(indexPath)
}
}
/// MARK: imagepicker delegate
extension GroupViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBAction func takePhotoAction() {
let vc = UIImagePickerController()
#if (arch(i386) || arch(x86_64))
vc.sourceType = .photoLibrary
#else
vc.sourceType = .camera
#endif
vc.delegate = self
present(vc, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
Toast.showActivity(message: "正在上传照片")
dismiss(animated: true) {
guard let image = info[.originalImage] as? UIImage,
let data = image.scaledImage(length: 1280, with: 0.4) else { return }
self.viewModel.submit(data: data)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
extension GroupViewController: NavigationBackViewController {}
extension GroupViewController: Storyboarded {
static func instantiate() -> GroupViewController {
return UIStoryboard.group.instantiateViewController(type: GroupViewController.self)
}
}
|