No Description

MessageListViewController.swift 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 var tableView: UITableView!
  20. var emptyView : UILabel = {
  21. let empty = UILabel(frame: CGRect(x: kScreenWidth / 2 - 50, y: 74, 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. }
  40. private func setNavigationBar() {
  41. title = type.model.title
  42. setRightBarButtonItem(image: UIImage.Navigation.verticalPoints, action: #selector(clearMessage))
  43. }
  44. private func setup() {
  45. setupReloadControl()
  46. setupLoadingControl()
  47. }
  48. private func setupReloadControl() {
  49. tableView.addPullToRefresh(PullToRefresh()) {
  50. [unowned self] in
  51. self.viewModel.reload()
  52. }
  53. tableView.startRefreshing(at: .top)
  54. }
  55. private func setupLoadingControl() {
  56. tableView.addPullToRefresh(PullToRefresh(position: .bottom)) {
  57. [unowned self] in
  58. self.viewModel.preload()
  59. }
  60. }
  61. // MARK: button function
  62. @objc func clearMessage() {
  63. let alert = ActionSheetController()
  64. alert.addAlertAction(AlertAction(title: "取消", style: .cancel))
  65. alert.addAlertAction(AlertAction(title: "清空消息", handler: { (item) in
  66. self.viewModel.removeAll()
  67. }))
  68. presentController(alert)
  69. }
  70. }
  71. fileprivate extension MessageListViewController {
  72. func observeMessage() {
  73. viewModel.showMessage
  74. .asDriver { _ in fatalError("Unexpected error from error messages observable.") }
  75. .drive(onNext: { message in
  76. Toast.show(message: message)
  77. })
  78. .disposed(by: disposeBag)
  79. }
  80. }
  81. fileprivate extension MessageListViewController {
  82. var dataSource: RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, MessageListItem>> {
  83. return RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, MessageListItem>>(configureCell: { (dataSource, tableView, indexPath, item) in
  84. switch self.type! {
  85. case .system:
  86. let cell = tableView.dequeueReusableCell(withIdentifier: "messageSystemCell", for: indexPath) as! MessageSystemCell
  87. cell.setInfo(item)
  88. return cell
  89. case .comment, .thumbup:
  90. let cell = tableView.dequeueReusableCell(withIdentifier: "messageCommentAndThumbupCell", for: indexPath) as! MessageCommentAndThumbupCell
  91. cell.setInfo(item)
  92. return cell
  93. }
  94. }, canEditRowAtIndexPath: { _, _ in true })
  95. }
  96. func binding() {
  97. observeMessage()
  98. bindViewModelToTableView()
  99. bindTableViewToViewModel()
  100. bindViewModelToRefreshing()
  101. }
  102. func bindViewModelToTableView() {
  103. viewModel.isEmpty
  104. .bind(to: emptyView.rx.isHidden)
  105. .disposed(by: disposeBag)
  106. viewModel.contents
  107. .bind(to: tableView.rx.items(dataSource: dataSource))
  108. .disposed(by: disposeBag)
  109. }
  110. func bindTableViewToViewModel() {
  111. tableView.rx.itemDeleted
  112. .asDriver()
  113. .drive(onNext: { [unowned self] in self.viewModel.remove(of: $0.row) })
  114. .disposed(by: disposeBag)
  115. tableView.rx.modelSelected(MessageListItem.self)
  116. .asDriver()
  117. .drive(onNext: { [unowned self] in self.viewModel.didSelect(item: $0) })
  118. .disposed(by: disposeBag)
  119. tableView.rx.willDisplayCell
  120. .asDriver()
  121. .drive(onNext: { [unowned self] in self.preload(indexPath: $0.indexPath) })
  122. .disposed(by: disposeBag)
  123. }
  124. func preload(indexPath: IndexPath) {
  125. guard indexPath.row == tableView.numberOfRows(inSection: 0) - 5 else { return }
  126. tableView.startRefreshing(at: .bottom)
  127. }
  128. func bindViewModelToRefreshing() {
  129. viewModel.isLoading
  130. .asDriver(onErrorJustReturn: true)
  131. .drive(onNext: {[weak self] flag in
  132. guard let `self` = self else { return }
  133. if flag {
  134. self.tableView.endRefreshing(at: .top)
  135. } else {
  136. self.tableView.endRefreshing(at: .bottom)
  137. }
  138. }).disposed(by: disposeBag)
  139. viewModel.hasMoreData
  140. .asDriver(onErrorJustReturn: true)
  141. .drive(onNext: {[weak self] flag in
  142. guard let `self` = self else { return }
  143. if flag {
  144. if self.tableView.bottomPullToRefresh == nil {
  145. self.setupLoadingControl()
  146. }
  147. } else {
  148. // self.tableViewt
  149. }
  150. }).disposed(by: disposeBag)
  151. }
  152. }
  153. extension MessageListViewController: NavigationBackViewController {}