No Description

GroupViewController.swift 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //
  2. // GroupViewController.swift
  3. // Paiai_iOS
  4. //
  5. // Created by FFIB 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. setupNavigationBar()
  52. }
  53. private func setup() {
  54. setupReloadControl()
  55. }
  56. private func setupReloadControl() {
  57. collectionView.addPullToRefresh(PullToRefresh()) {
  58. [weak self] in
  59. guard let `self` = self else { return }
  60. self.viewModel.reload()
  61. }
  62. collectionView.startRefreshing(at: .top)
  63. }
  64. deinit {
  65. collectionView.endAllRefreshing()
  66. }
  67. }
  68. /// UI bindings
  69. fileprivate extension GroupViewController {
  70. var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
  71. return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(configureCell:
  72. { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
  73. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCell
  74. cell.setInfo(item, source: .group)
  75. return cell
  76. })
  77. }
  78. func binding() {
  79. bindViewModelToEmptyView()
  80. bindViewModelToQRImageView()
  81. bindViewModelToRefreshing()
  82. bindCollectionViewDelegate()
  83. bindViewModelToCollectionView()
  84. bindCollectionViewToViewModel()
  85. bindViewModelToNavigationBarImage()
  86. bindViewModelToNavigationBarTitle()
  87. }
  88. func bindViewModelToEmptyView() {
  89. viewModel.hasData.bind(to: emptyView.rx.isHidden).disposed(by: disposeBag)
  90. }
  91. func bindViewModelToQRImageView() {
  92. viewModel.groupItem.map { UIImage(qr: "https:api.pai.ai/g/\($0.group_id)") }.bind(to: qrImageView.rx.image).disposed(by: disposeBag)
  93. }
  94. func bindViewModelToRefreshing() {
  95. viewModel.isLoading
  96. .subscribe(onNext: {[unowned self] flag in
  97. self.collectionView.endRefreshing(at: .top)
  98. }).disposed(by: disposeBag)
  99. }
  100. func bindCollectionViewDelegate() {
  101. collectionView.rx.setDelegate(self).disposed(by: disposeBag)
  102. }
  103. func bindViewModelToCollectionView() {
  104. viewModel.contents
  105. .bind(to: collectionView.rx.items(dataSource: dataSource))
  106. .disposed(by: disposeBag)
  107. }
  108. func bindCollectionViewToViewModel() {
  109. collectionView.rx.itemSelected
  110. .asDriver()
  111. .drive(onNext: { [unowned self] in self.viewModel.didSelect($0.item) })
  112. .disposed(by: disposeBag)
  113. }
  114. func bindViewModelToNavigationBarTitle() {
  115. viewModel.groupName.bind(to: navigationBarViewTitle.rx.text).disposed(by: disposeBag)
  116. }
  117. func bindViewModelToNavigationBarImage() {
  118. viewModel.groupAvatar
  119. .subscribe(onNext: {[weak self] (avatar) in
  120. guard let `self` = self else { return }
  121. self.navigationBarViewImage.image = UIImage(named: avatar)
  122. }).disposed(by: disposeBag)
  123. }
  124. }
  125. extension GroupViewController {
  126. func setupNavigationBar() {
  127. guard navigationViewNotReady else { return }
  128. setRightBarButtonItems()
  129. constructNaivgationViewHierarchy()
  130. activateConstraintsNavigation()
  131. navigationViewNotReady = false
  132. }
  133. private func constructNaivgationViewHierarchy() {
  134. navigationItem.titleView = navigationBarView
  135. navigationBarView.addSubview(navigationBarViewImage)
  136. navigationBarView.addSubview(navigationBarViewTitle)
  137. }
  138. private func setRightBarButtonItems() {
  139. let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
  140. UIImage(named: "navigation-right")],
  141. targets: [self, viewModel!],
  142. actions: [#selector(GroupViewController.presentGroupQR),
  143. #selector(GroupViewModel.navigateToGroupDetail)])
  144. navigationItem.setRightItem(item)
  145. }
  146. @objc func presentGroupQR() {
  147. let groupItem = viewModel.groupItem.value
  148. let alert = AlertViewController(style: .custom(GroupQRView(groupName: groupItem.group_name,
  149. groupAvatar: "Group\(groupItem.group_default_avatar)",
  150. groupQR: "https:api.pai.ai/g/\(groupItem.group_id)"),
  151. AlertAnimator()) )
  152. presentController(alert)
  153. }
  154. }
  155. /// navigation bar layout
  156. fileprivate extension GroupViewController {
  157. func activateConstraintsNavigation() {
  158. activateConstraintsNavigationBarViewImage()
  159. activateConstraintsNavigationBarViewTitle()
  160. if #available(iOS 11, *) { return }
  161. navigationBarViewTitle.sizeToFit()
  162. navigationBarView.frame.size = CGSize(width: navigationBarViewTitle.bounds.size.width + 42, height: 36)
  163. }
  164. func activateConstraintsNavigationBarViewTitle() {
  165. navigationBarViewTitle.translatesAutoresizingMaskIntoConstraints = false
  166. NSLayoutConstraint.activate([
  167. navigationBarViewTitle.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
  168. navigationBarViewTitle.widthAnchor.constraint(lessThanOrEqualToConstant: view.width - 200),
  169. navigationBarViewTitle.trailingAnchor.constraint(equalTo: navigationBarView.trailingAnchor),
  170. navigationBarViewTitle.leadingAnchor.constraint(equalTo: navigationBarViewImage.trailingAnchor, constant: 6)
  171. ])
  172. }
  173. func activateConstraintsNavigationBarViewImage() {
  174. navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
  175. NSLayoutConstraint.activate([
  176. navigationBarViewImage.widthAnchor.constraint(equalToConstant: 36),
  177. navigationBarViewImage.heightAnchor.constraint(equalToConstant: 36),
  178. navigationBarViewImage.topAnchor.constraint(equalTo: navigationBarView.topAnchor),
  179. navigationBarViewImage.bottomAnchor.constraint(equalTo: navigationBarView.bottomAnchor),
  180. navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor),
  181. ])
  182. }
  183. }
  184. extension GroupViewController: UICollectionViewDelegateFlowLayout {
  185. func collectionView(_ collectionView: UICollectionView,
  186. layout collectionViewLayout: UICollectionViewLayout,
  187. sizeForItemAt indexPath: IndexPath) -> CGSize {
  188. return viewModel.layoutSizeForIndexPath(indexPath)
  189. }
  190. }
  191. /// MARK: imagepicker delegate
  192. extension GroupViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  193. @IBAction func takePhotoAction() {
  194. let vc = UIImagePickerController()
  195. #if (arch(i386) || arch(x86_64))
  196. vc.sourceType = .photoLibrary
  197. #else
  198. vc.sourceType = .camera
  199. #endif
  200. vc.delegate = self
  201. present(vc, animated: true, completion: nil)
  202. }
  203. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
  204. Toast.showActivity(message: "正在上传照片")
  205. dismiss(animated: true) {
  206. guard let image = info[.originalImage] as? UIImage,
  207. let data = image.scaledImage(length: 1280, with: 0.4) else { return }
  208. self.viewModel.submit(data: data)
  209. }
  210. }
  211. func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
  212. dismiss(animated: true, completion: nil)
  213. }
  214. }
  215. extension GroupViewController: NavigationBackViewController {}
  216. extension GroupViewController: Storyboarded {
  217. static func instantiate() -> GroupViewController {
  218. return UIStoryboard.group.instantiateViewController(type: GroupViewController.self)
  219. }
  220. }