Nessuna descrizione

MessageListViewController.swift 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //
  2. // MessageListViewController.swift
  3. // PaiAi
  4. //
  5. // Created by mac on 16/5/13.
  6. // Copyright © 2016年 FFIB. All rights reserved.
  7. //
  8. import UIKit
  9. import RxSwift
  10. import RxCocoa
  11. import RxDataSources
  12. import PaiaiDataKit
  13. import PaiaiUIKit
  14. import PullToRefresh
  15. protocol MessageViewControllerDelegate: class {
  16. func didSelect(item: MessageItem)
  17. }
  18. final class MessageListViewController: UIViewController {
  19. @IBOutlet weak var tableView: UITableView!
  20. var emptyView : UILabel = {
  21. let empty = UILabel(frame: CGRect(x: kScreenWidth / 2 - 50, y: 5, width: 50, height: 50))
  22. empty.isHidden = true
  23. empty.text = "当前没有任何消息"
  24. empty.textColor = UIColor.gray
  25. empty.font = UIFont.systemFont(ofSize: 14)
  26. empty.sizeToFit()
  27. return empty
  28. }()
  29. var viewModel: MessageListViewModel!
  30. var type: MessageType!
  31. fileprivate let disposeBag = DisposeBag()
  32. // MARK: view function
  33. override func viewDidLoad() {
  34. super.viewDidLoad()
  35. view.addSubview(emptyView)
  36. setup()
  37. binding()
  38. setNavigationBar()
  39. self.viewModel.reload()
  40. }
  41. private func setNavigationBar() {
  42. title = type.model.title
  43. setRightBarButtonItem(image: UIImage.Navigation.right, action: #selector(clearMessage))
  44. }
  45. private func setup() {
  46. setupReloadControl()
  47. setupLoadingControl()
  48. }
  49. private func setupReloadControl() {
  50. tableView.addPullToRefresh(PullToRefresh()) {
  51. [weak self] in
  52. guard let `self` = self else { return }
  53. self.viewModel.reload()
  54. }
  55. tableView.startRefreshing(at: .top)
  56. }
  57. private func setupLoadingControl() {
  58. tableView.addPullToRefresh(PullToRefresh(position: .bottom)) {
  59. [weak self] in
  60. guard let `self` = self else { return }
  61. self.viewModel.preload()
  62. }
  63. }
  64. // MARK: button function
  65. @objc func clearMessage() {
  66. let alert = ActionSheetController()
  67. alert.addAlertAction(AlertAction(title: "取消", style: .cancel))
  68. alert.addAlertAction(AlertAction(title: "清空消息", handler: { _ in
  69. self.viewModel.removeAll()
  70. }))
  71. presentController(alert)
  72. }
  73. }
  74. fileprivate extension MessageListViewController {
  75. func observeMessage() {
  76. viewModel.showMessage
  77. .asDriver { _ in fatalError("Unexpected error from error messages observable.") }
  78. .drive(onNext: { message in
  79. Toast.show(message: message)
  80. })
  81. .disposed(by: disposeBag)
  82. }
  83. }
  84. fileprivate extension MessageListViewController {
  85. var dataSource: RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, MessageListItem>> {
  86. return RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, MessageListItem>>(
  87. configureCell: { (dataSource, tableView, indexPath, item) in
  88. switch self.type! {
  89. case .system:
  90. let cell = tableView.dequeueReusableCell(withIdentifier: "messageSystemCell", for: indexPath) as! MessageSystemCell
  91. cell.setInfo(item)
  92. return cell
  93. case .comment, .thumbup:
  94. let cell = tableView.dequeueReusableCell(withIdentifier: "messageCommentAndThumbupCell", for: indexPath) as! MessageCommentAndThumbupCell
  95. cell.setInfo(item)
  96. return cell
  97. }
  98. }, canEditRowAtIndexPath: { _, _ in true })
  99. }
  100. func binding() {
  101. observeMessage()
  102. bindViewModelToTableView()
  103. bindTableViewToViewModel()
  104. bindViewModelToRefreshing()
  105. }
  106. func bindViewModelToTableView() {
  107. viewModel.isEmpty
  108. .bind(to: emptyView.rx.isHidden)
  109. .disposed(by: disposeBag)
  110. viewModel.contents
  111. .bind(to: tableView.rx.items(dataSource: dataSource))
  112. .disposed(by: disposeBag)
  113. }
  114. func bindTableViewToViewModel() {
  115. tableView.rx.itemDeleted
  116. .asDriver()
  117. .drive(onNext: { [unowned self] in self.viewModel.remove(of: $0.row) })
  118. .disposed(by: disposeBag)
  119. tableView.rx.modelSelected(MessageListItem.self)
  120. .asDriver()
  121. .drive(onNext: { [unowned self] in self.viewModel.didSelect(item: $0) })
  122. .disposed(by: disposeBag)
  123. tableView.rx.willDisplayCell
  124. .asDriver()
  125. .drive(onNext: { [unowned self] in self.preload(indexPath: $0.indexPath) })
  126. .disposed(by: disposeBag)
  127. }
  128. func preload(indexPath: IndexPath) {
  129. guard indexPath.row == tableView.numberOfRows(inSection: 0) - 5 else { return }
  130. tableView.startRefreshing(at: .bottom)
  131. }
  132. func bindViewModelToRefreshing() {
  133. viewModel.isLoading
  134. .asDriver(onErrorJustReturn: true)
  135. .drive(onNext: {[weak self] flag in
  136. guard let `self` = self else { return }
  137. if flag {
  138. self.tableView.endRefreshing(at: .top)
  139. } else {
  140. self.tableView.endRefreshing(at: .bottom)
  141. }
  142. }).disposed(by: disposeBag)
  143. viewModel.hasMoreData
  144. .asDriver(onErrorJustReturn: true)
  145. .drive(onNext: {[weak self] flag in
  146. guard let `self` = self else { return }
  147. if flag {
  148. if self.tableView.bottomPullToRefresh == nil {
  149. self.setupLoadingControl()
  150. }
  151. } else {
  152. // self.tableViewt
  153. }
  154. }).disposed(by: disposeBag)
  155. }
  156. }
  157. extension MessageListViewController: NavigationBackViewController {}