ChatViewController.m 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. //
  2. // ChatViewController.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by Kyle on 2022/3/17.
  6. //
  7. #import "ChatViewController.h"
  8. #import "ChatNavView.h"
  9. #import "CreateFansGroupViewController.h"
  10. #import "ChatAddressViewController.h"
  11. #import "KSChatListViewController.h"
  12. #import "KSTabBarViewController.h"
  13. #import "TXIMLinsenter.h"
  14. @interface ChatViewController ()<JXCategoryViewDelegate>
  15. @property (nonatomic, strong) ChatNavView *navView;
  16. @property (nonatomic, strong) JXCategoryTitleView *myCategoryView;
  17. @property (nonatomic, assign) NSInteger currentIndex;
  18. @property (nonatomic, strong) KSChatListViewController *chatListCtrl;
  19. @property (nonatomic, strong) ChatAddressViewController *contractList;
  20. @end
  21. @implementation ChatViewController
  22. - (void)viewDidLoad {
  23. [super viewDidLoad];
  24. // Do any additional setup after loading the view.
  25. self.ks_prefersNavigationBarHidden = YES;
  26. self.titles = @[@"聊天", @"联系人"];
  27. [self getUnreadCount];
  28. [self configUI];
  29. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshChatList) name:CHATVIEW_REFRESH object:nil];
  30. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshMessageStatus:) name:CHATVIEW_REFRESHSTATUS object:nil];
  31. }
  32. - (void)getUnreadCount {
  33. [TXIM_LINSENTER getUnReadCountCallback:^(NSInteger count) {
  34. dispatch_async(dispatch_get_main_queue(),^{
  35. if (count >= 1) {
  36. self.navView.dotView.hidden = NO;
  37. } else {
  38. self.navView.dotView.hidden = YES;
  39. }
  40. });
  41. }];
  42. }
  43. - (void)refreshMessageStatus:(NSNotification *)notification {
  44. NSDictionary *msgDic = notification.object; ///
  45. NSInteger unreadMsgCount = [msgDic ks_integerValueForKey:@"unreadCount"];
  46. if (unreadMsgCount >= 1) {
  47. self.navView.dotView.hidden = NO;
  48. } else {
  49. self.navView.dotView.hidden = YES;
  50. }
  51. }
  52. - (void)refreshChatList {
  53. if (self.chatListCtrl && self.currentIndex == 0) {
  54. [self.chatListCtrl refreshChatListMessage];
  55. }
  56. }
  57. - (void)configUI {
  58. [self.scrollView removeFromSuperview];
  59. if ([UserDefault(TENANT_ID) integerValue] > 0) { // 机构背景
  60. UIImage *bgImage = [UIImage imageNamed:@"tenant_chatBg"];
  61. CGFloat height = bgImage.size.height / bgImage.size.width * KPortraitWidth;
  62. UIImageView *imageView = [[UIImageView alloc] initWithImage:bgImage];
  63. imageView.frame = CGRectMake(0, 0, KPortraitWidth, height);
  64. [self.view addSubview:imageView];
  65. }
  66. [self.view addSubview:self.navView];
  67. CGFloat topSpace = kNaviBarHeight;
  68. self.myCategoryView.frame = CGRectMake(0, topSpace, KPortraitWidth, 10);
  69. self.myCategoryView.backgroundColor = HexRGB(0xf6f8f9);
  70. self.myCategoryView.titles = self.titles;
  71. self.myCategoryView.titleFont = [UIFont systemFontOfSize:16.0f];
  72. self.myCategoryView.titleSelectedFont = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
  73. self.myCategoryView.titleSelectedColor = CLIENT_THEMECOLOR;
  74. self.myCategoryView.titleColor = HexRGB(0x777777);
  75. self.myCategoryView.titleColorGradientEnabled = YES;
  76. self.myCategoryView.hidden = YES;
  77. self.myCategoryView.backgroundColor = [UIColor clearColor];
  78. [self.view addSubview:self.categoryView];
  79. [self.view addSubview:self.listContainerView];
  80. }
  81. - (void)viewDidLayoutSubviews {
  82. [super viewDidLayoutSubviews];
  83. CGFloat topSpace = kNaviBarHeight;
  84. self.categoryView.frame = CGRectMake(0, topSpace, self.view.bounds.size.width, [self preferredCategoryViewHeight]);
  85. self.listContainerView.frame = CGRectMake(0, topSpace + [self preferredCategoryViewHeight], self.view.bounds.size.width, self.view.bounds.size.height - topSpace - [self preferredCategoryViewHeight]);
  86. }
  87. - (void)viewDidAppear:(BOOL)animated {
  88. [super viewDidAppear:animated];
  89. // 处于第一个item的时候,才允许屏幕边缘手势返回
  90. self.navigationController.interactivePopGestureRecognizer.enabled = (self.categoryView.selectedIndex == 0);
  91. }
  92. - (void)scrollToFirstPage {
  93. [self.myCategoryView selectItemAtIndex:0];
  94. }
  95. - (void)viewWillDisappear:(BOOL)animated {
  96. [super viewWillDisappear:animated];
  97. // 离开页面的时候,需要恢复屏幕边缘手势,不能影响其他页面
  98. self.navigationController.interactivePopGestureRecognizer.enabled = YES;
  99. }
  100. - (JXCategoryTitleView *)myCategoryView {
  101. return (JXCategoryTitleView *)self.categoryView;
  102. }
  103. - (CGFloat)preferredCategoryViewHeight {
  104. return CGFLOAT_MIN;
  105. }
  106. - (JXCategoryBaseView *)preferredCategoryView {
  107. return [[JXCategoryTitleView alloc] init];
  108. }
  109. #pragma mark - JXCategoryViewDelegate
  110. // 点击选中或者滚动选中都会调用该方法。适用于只关心选中事件,不关心具体是点击还是滚动选中的。
  111. - (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
  112. NSLog(@"%@", NSStringFromSelector(_cmd));
  113. // bool scrollChatTable = index == 0 ? YES : NO;
  114. // [self.navView scrollChatTable:scrollChatTable];
  115. // 侧滑手势处理
  116. self.navigationController.interactivePopGestureRecognizer.enabled = (index == 0);
  117. }
  118. #pragma mark - JXCategoryListContainerViewDelegate
  119. - (id<JXCategoryListContentViewDelegate>)listContainerView:(JXCategoryListContainerView *)listContainerView initListForIndex:(NSInteger)index {
  120. if (index == 0) {
  121. KSChatListViewController *listVC = [[KSChatListViewController alloc] init];
  122. listVC.view.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - kNaviBarHeight - kTabBarHeight);
  123. self.chatListCtrl = listVC;
  124. return listVC;
  125. }
  126. else {
  127. ChatAddressViewController *list = [[ChatAddressViewController alloc] init];
  128. MJWeakSelf;
  129. [list scrollActionCallback:^(NSInteger scrollIndex) {
  130. [weakSelf contractScrollIndex:scrollIndex];
  131. }];
  132. self.contractList = list;
  133. list.titles = @[@"群组",@"联系人",@"黑名单"];
  134. return list;
  135. }
  136. }
  137. - (void)contractScrollIndex:(NSInteger)scrollIndex {
  138. [self.navView scrollChatTableIndex:scrollIndex+1];
  139. }
  140. // 返回列表的数量
  141. - (NSInteger)numberOfListsInlistContainerView:(JXCategoryListContainerView *)listContainerView {
  142. return self.titles.count;
  143. }
  144. #pragma mark - JXCategoryListContainerViewDelegate
  145. - (void)listContainerViewDidScroll:(UIScrollView *)scrollView{
  146. if ([self isKindOfClass:[ChatAddressViewController class]]) {
  147. CGFloat index = scrollView.contentOffset.x/scrollView.bounds.size.width;
  148. CGFloat absIndex = fabs(index - self.currentIndex);
  149. if (absIndex >= 1) {
  150. //”快速滑动的时候,只响应最外层VC持有的scrollView“,说实话,完全可以不用处理这种情况。如果你们的产品经理坚持认为这是个问题,就把这块代码加上吧。
  151. //嵌套使用的时候,最外层的VC持有的scrollView在翻页之后,就断掉一次手势。解决快速滑动的时候,只响应最外层VC持有的scrollView。子VC持有的scrollView却没有响应
  152. self.listContainerView.scrollView.panGestureRecognizer.enabled = NO;
  153. self.listContainerView.scrollView.panGestureRecognizer.enabled = YES;
  154. _currentIndex = floor(index);
  155. }
  156. }
  157. }
  158. - (ChatNavView *)navView {
  159. if (!_navView) {
  160. _navView = [ChatNavView shareInstance];
  161. _navView.frame = CGRectMake(0, 0, KPortraitWidth, kNaviBarHeight);
  162. MJWeakSelf;
  163. [_navView chatNavAction:^(CHATNAVACTION action) {
  164. [weakSelf navAction:action];
  165. }];
  166. }
  167. return _navView;
  168. }
  169. - (void)navAction:(CHATNAVACTION)action {
  170. switch (action) {
  171. case CHATNAVACTION_LIST:
  172. {
  173. [self.categoryView selectItemAtIndex:0];
  174. }
  175. break;
  176. case CHATNAVACTION_GROUP: // 群组
  177. {
  178. [self.categoryView selectItemAtIndex:1];
  179. [self.contractList scrollToChatList:NO];
  180. }
  181. break;
  182. case CHATNAVACTION_CONTACTS: // 联系人
  183. {
  184. [self.categoryView selectItemAtIndex:1];
  185. [self.contractList scrollToChatList:YES];
  186. }
  187. break;
  188. case CHATNAVACTION_BLACKLIST:
  189. {
  190. [self.categoryView selectItemAtIndex:1];
  191. [self.contractList scrollToChatList:CHAT_ADDRESS_BLACKLIST];
  192. }
  193. break;
  194. default:
  195. break;
  196. }
  197. }
  198. #pragma mark - Custom Accessors
  199. // 分页菜单视图
  200. - (JXCategoryBaseView *)categoryView {
  201. if (!_categoryView) {
  202. _categoryView = [self preferredCategoryView];
  203. _categoryView.delegate = self;
  204. // !!!: 将列表容器视图关联到 categoryView
  205. _categoryView.listContainer = self.listContainerView;
  206. }
  207. return _categoryView;
  208. }
  209. // 列表容器视图
  210. - (JXCategoryListContainerView *)listContainerView {
  211. if (!_listContainerView) {
  212. _listContainerView = [[JXCategoryListContainerView alloc] initWithType:JXCategoryListContainerType_ScrollView delegate:self];
  213. _listContainerView.scrollView.scrollEnabled = NO;
  214. }
  215. return _listContainerView;
  216. }
  217. /*
  218. #pragma mark - Navigation
  219. // In a storyboard-based application, you will often want to do a little preparation before navigation
  220. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  221. // Get the new view controller using [segue destinationViewController].
  222. // Pass the selected object to the new view controller.
  223. }
  224. */
  225. @end