No Description

GroupViewController.swift 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. //
  2. // GroupViewController.swift
  3. // PaiAi
  4. //
  5. // Created by zhengjianfei on 16/3/28.
  6. // Copyright © 2016年 FFIB. All rights reserved.
  7. //
  8. import UIKit
  9. import RxSwift
  10. import RxCocoa
  11. import RxDataSources
  12. import PaiaiUIKit
  13. import PaiaiDataKit
  14. import PullToRefresh
  15. final class GroupViewController: UIViewController {
  16. // MARK: Storyboard property
  17. @IBOutlet weak var collectionView: UICollectionView!
  18. @IBOutlet weak var photographBtn: UIButton!
  19. @IBOutlet weak var emptyView: UIStackView!
  20. @IBOutlet weak var qrImageView: UIImageView!
  21. // MARK: custom UI property
  22. var navigationBarView: UIView = {
  23. let view = UIView()
  24. view.alpha = 0
  25. return view
  26. }()
  27. var navigationBarViewTitle: UILabel = {
  28. let label = UILabel()
  29. label.textColor = UIColor.white
  30. return label
  31. }()
  32. var navigationBarViewImage: UIImageView = {
  33. let image = UIImageView()
  34. image.cornerRadius = 18
  35. return image
  36. }()
  37. // MARK: data property
  38. var viewModel: GroupViewModel!
  39. fileprivate var navigationViewNotReady = true
  40. fileprivate let disposeBag = DisposeBag()
  41. override func viewDidLoad() {
  42. super.viewDidLoad()
  43. initalize()
  44. }
  45. func initalize() {
  46. collectionView.register(UINib(nibName: "PhotoCell",
  47. bundle: Bundle(identifier: "com.Paiai-iOS")),
  48. forCellWithReuseIdentifier: "photoCell")
  49. setup()
  50. binding()
  51. }
  52. private func setup() {
  53. setupReloadControl()
  54. }
  55. private func setupReloadControl() {
  56. collectionView.addPullToRefresh(PullToRefresh()) {
  57. [weak self] in
  58. guard let `self` = self else { return }
  59. self.viewModel.reload()
  60. }
  61. collectionView.startRefreshing(at: .top)
  62. }
  63. }
  64. /// UI bindings
  65. fileprivate extension GroupViewController {
  66. var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
  67. return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(configureCell:
  68. { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
  69. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCell
  70. cell.setInfo(item, source: .group)
  71. return cell
  72. })
  73. }
  74. func binding() {
  75. bindViewModelToEmptyView()
  76. bindViewModelToQRImageView()
  77. bindViewModelToRefreshing()
  78. bindCollectionViewDelegate()
  79. bindViewModelToCollectionView()
  80. bindCollectionViewToViewModel()
  81. bindViewModelToNavigationBarImage()
  82. bindViewModelToNavigationBarTitle()
  83. }
  84. func bindViewModelToEmptyView() {
  85. viewModel.hasData.bind(to: emptyView.rx.isHidden).disposed(by: disposeBag)
  86. }
  87. func bindViewModelToQRImageView() {
  88. viewModel.groupItem.map { UIImage(qr: "https:api.pai.ai/g/\($0.group_id)") }.bind(to: qrImageView.rx.image).disposed(by: disposeBag)
  89. }
  90. func bindViewModelToRefreshing() {
  91. viewModel.isLoading
  92. .subscribe(onNext: {[unowned self] flag in
  93. self.collectionView.endRefreshing(at: .top)
  94. }).disposed(by: disposeBag)
  95. }
  96. func bindCollectionViewDelegate() {
  97. collectionView.rx.setDelegate(self).disposed(by: disposeBag)
  98. }
  99. func bindViewModelToCollectionView() {
  100. viewModel.contents
  101. .bind(to: collectionView.rx.items(dataSource: dataSource))
  102. .disposed(by: disposeBag)
  103. }
  104. func bindCollectionViewToViewModel() {
  105. collectionView.rx.itemSelected
  106. .asDriver()
  107. .drive(onNext: { [unowned self] in self.viewModel.didSelect($0.item) })
  108. .disposed(by: disposeBag)
  109. }
  110. func bindViewModelToNavigationBarTitle() {
  111. viewModel.groupName.bind(to: navigationBarViewTitle.rx.text).disposed(by: disposeBag)
  112. }
  113. func bindViewModelToNavigationBarImage() {
  114. viewModel.groupAvatar
  115. .subscribe(onNext: {[weak self] (avatar) in
  116. guard let `self` = self else { return }
  117. self.navigationBarViewImage.image = UIImage(named: avatar)
  118. }).disposed(by: disposeBag)
  119. }
  120. }
  121. extension GroupViewController: NavigationBarInteractiveViewController {
  122. var navigationView: UIView {
  123. return navigationBarView
  124. }
  125. func setNavigationBar() {
  126. guard navigationViewNotReady else { return }
  127. setRightBarButtonItems()
  128. construvtNaivgationViewHierarchy()
  129. activateConstraintsNavigation()
  130. navigationViewNotReady = false
  131. }
  132. private func construvtNaivgationViewHierarchy() {
  133. navigationController?.navigationBar.addSubview(navigationBarView)
  134. navigationBarView.addSubview(navigationBarViewImage)
  135. navigationBarView.addSubview(navigationBarViewTitle)
  136. }
  137. private func setRightBarButtonItems() {
  138. let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
  139. UIImage(named: "navigation-right")],
  140. targets: [self, viewModel],
  141. actions: [#selector(GroupViewController.presentGroupQR),
  142. #selector(GroupViewModel.navigateToGroupDetail)])
  143. navigationItem.rightBarButtonItem = item
  144. }
  145. @objc func presentGroupQR() {
  146. let groupItem = viewModel.groupItem.value
  147. let alert = AlertViewController(style: .custom(GroupQRView(groupName: groupItem.group_name,
  148. groupAvatar: "Group\(groupItem.group_default_avatar)",
  149. groupQR: "https:api.pai.ai/g/\(groupItem.group_id)"),
  150. AlertAnimator()) )
  151. presentController(alert)
  152. }
  153. }
  154. /// navigation bar layout
  155. fileprivate extension GroupViewController {
  156. func activateConstraintsNavigation() {
  157. activateConstraintsNavigationBarView()
  158. activateConstraintsNavigationBarViewImage()
  159. activateConstraintsNavigationBarViewTitle()
  160. }
  161. func activateConstraintsNavigationBarView() {
  162. guard let barContentView = navigationController?.navigationBar else { return }
  163. navigationBarView.translatesAutoresizingMaskIntoConstraints = false
  164. NSLayoutConstraint.activate([
  165. navigationBarView.topAnchor.constraint(equalTo: barContentView.topAnchor),
  166. navigationBarView.bottomAnchor.constraint(equalTo: barContentView.bottomAnchor),
  167. navigationBarView.centerXAnchor.constraint(equalTo: barContentView.centerXAnchor)
  168. ])
  169. }
  170. func activateConstraintsNavigationBarViewTitle() {
  171. navigationBarViewTitle.translatesAutoresizingMaskIntoConstraints = false
  172. NSLayoutConstraint.activate([
  173. navigationBarViewTitle.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
  174. navigationBarViewTitle.leadingAnchor.constraint(equalTo: navigationBarViewImage.trailingAnchor, constant: 6),
  175. navigationBarViewTitle.trailingAnchor.constraint(equalTo: navigationBarView.trailingAnchor),
  176. navigationBarViewTitle.widthAnchor.constraint(lessThanOrEqualToConstant: view.width - 200)
  177. ])
  178. }
  179. func activateConstraintsNavigationBarViewImage() {
  180. navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
  181. NSLayoutConstraint.activate([
  182. navigationBarViewImage.widthAnchor.constraint(equalToConstant: 36),
  183. navigationBarViewImage.heightAnchor.constraint(equalToConstant: 36),
  184. navigationBarViewImage.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
  185. navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor),
  186. ])
  187. }
  188. }
  189. extension GroupViewController: UICollectionViewDelegateFlowLayout {
  190. func collectionView(_ collectionView: UICollectionView,
  191. layout collectionViewLayout: UICollectionViewLayout,
  192. sizeForItemAt indexPath: IndexPath) -> CGSize {
  193. return viewModel.layoutSizeForIndexPath(indexPath)
  194. }
  195. }
  196. /// MARK: imagepicker delegate
  197. extension GroupViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  198. @IBAction func takePhotoAction() {
  199. let vc = UIImagePickerController()
  200. #if (arch(i386) || arch(x86_64))
  201. vc.sourceType = .photoLibrary
  202. #else
  203. vc.sourceType = .camera
  204. #endif
  205. vc.delegate = self
  206. present(vc, animated: true, completion: nil)
  207. }
  208. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
  209. dismiss(animated: true, completion: nil)
  210. guard let image = info[.originalImage] as? UIImage,
  211. let data = image.scaledImage(length: 1280, with: 0.4) else { return }
  212. viewModel.submit(data: data)
  213. }
  214. func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
  215. dismiss(animated: true, completion: nil)
  216. }
  217. }
  218. extension GroupViewController: NavigationBackViewController {}
  219. extension GroupViewController: Storyboarded {
  220. static func instantiate() -> GroupViewController {
  221. let vc = UIStoryboard.group.instantiateController(GroupViewController.self)
  222. return vc
  223. }
  224. }