TUIFaceView.m 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //
  2. // TUIFaceView.m
  3. // UIKit
  4. //
  5. // Created by kennethmiao on 2018/9/18.
  6. // Copyright © 2018 Tencent. All rights reserved.
  7. //
  8. #import "TUIFaceView.h"
  9. #import <TIMCommon/TIMCommonModel.h>
  10. #import <TIMCommon/TIMDefine.h>
  11. #import <TUICore/TUIThemeManager.h>
  12. @interface TUIFaceView () <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
  13. @property(nonatomic, strong) NSMutableArray *sectionIndexInGroup;
  14. @property(nonatomic, strong) NSMutableArray *pageCountInGroup;
  15. @property(nonatomic, strong) NSMutableArray *groupIndexInSection;
  16. @property(nonatomic, strong) NSMutableDictionary *itemIndexs;
  17. @property(nonatomic, assign) NSInteger sectionCount;
  18. @property(nonatomic, assign) NSInteger curGroupIndex;
  19. @end
  20. @implementation TUIFaceView
  21. - (id)initWithFrame:(CGRect)frame {
  22. self = [super initWithFrame:frame];
  23. if (self) {
  24. [self setupViews];
  25. [self defaultLayout];
  26. }
  27. return self;
  28. }
  29. - (void)setupViews {
  30. self.backgroundColor = TUIChatDynamicColor(@"chat_input_controller_bg_color", @"#EBF0F6");
  31. _faceFlowLayout = [[TUICollectionRTLFitFlowLayout alloc] init];
  32. _faceFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  33. _faceFlowLayout.minimumLineSpacing = TFaceView_Margin;
  34. _faceFlowLayout.minimumInteritemSpacing = TFaceView_Margin;
  35. _faceFlowLayout.sectionInset = UIEdgeInsetsMake(0, TFaceView_Page_Padding, 0, TFaceView_Page_Padding);
  36. _faceCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_faceFlowLayout];
  37. [_faceCollectionView registerClass:[TUIFaceCell class] forCellWithReuseIdentifier:TFaceCell_ReuseId];
  38. _faceCollectionView.collectionViewLayout = _faceFlowLayout;
  39. _faceCollectionView.pagingEnabled = YES;
  40. _faceCollectionView.delegate = self;
  41. _faceCollectionView.dataSource = self;
  42. _faceCollectionView.showsHorizontalScrollIndicator = NO;
  43. _faceCollectionView.showsVerticalScrollIndicator = NO;
  44. _faceCollectionView.backgroundColor = self.backgroundColor;
  45. _faceCollectionView.alwaysBounceHorizontal = YES;
  46. [self addSubview:_faceCollectionView];
  47. _lineView = [[UIView alloc] init];
  48. _lineView.backgroundColor = TIMCommonDynamicColor(@"separator_color", @"#DBDBDB");
  49. _pageControl = [[UIPageControl alloc] init];
  50. _pageControl.currentPageIndicatorTintColor = TUIChatDynamicColor(@"chat_face_page_control_current_color", @"#7D7D7D");
  51. _pageControl.pageIndicatorTintColor = TUIChatDynamicColor(@"chat_face_page_control_color", @"#DEDEDE");
  52. _pageControl.userInteractionEnabled = NO;
  53. [self addSubview:_pageControl];
  54. }
  55. - (void)layoutSubviews {
  56. [super layoutSubviews];
  57. [self defaultLayout];
  58. }
  59. - (void)defaultLayout {
  60. _lineView.frame = CGRectMake(0, 0, self.frame.size.width, TLine_Heigh);
  61. _pageControl.frame = CGRectMake(0, self.frame.size.height - TFaceView_Page_Height, self.frame.size.width, TFaceView_Page_Height);
  62. _faceCollectionView.frame = CGRectMake(0, _lineView.frame.origin.y + _lineView.frame.size.height + TFaceView_Margin, self.frame.size.width,
  63. self.frame.size.height - _pageControl.frame.size.height - _lineView.frame.size.height - 2 * TFaceView_Margin);
  64. }
  65. - (void)setData:(NSMutableArray *)data {
  66. _faceGroups = data;
  67. [self defaultLayout];
  68. _sectionIndexInGroup = [NSMutableArray array];
  69. _groupIndexInSection = [NSMutableArray array];
  70. _itemIndexs = [NSMutableDictionary dictionary];
  71. _pageCountInGroup = [NSMutableArray array];
  72. NSInteger sectionIndex = 0;
  73. for (NSInteger groupIndex = 0; groupIndex < _faceGroups.count; ++groupIndex) {
  74. TUIFaceGroup *group = _faceGroups[groupIndex];
  75. [_sectionIndexInGroup addObject:@(sectionIndex)];
  76. int itemCount = group.rowCount * group.itemCountPerRow;
  77. int sectionCount = ceil(group.faces.count * 1.0 / (itemCount - (group.needBackDelete ? 1 : 0)));
  78. [_pageCountInGroup addObject:@(sectionCount)];
  79. for (int sectionIndex = 0; sectionIndex < sectionCount; ++sectionIndex) {
  80. [_groupIndexInSection addObject:@(groupIndex)];
  81. }
  82. sectionIndex += sectionCount;
  83. }
  84. _sectionCount = sectionIndex;
  85. for (NSInteger curSection = 0; curSection < _sectionCount; ++curSection) {
  86. NSNumber *groupIndex = _groupIndexInSection[curSection];
  87. NSNumber *groupSectionIndex = _sectionIndexInGroup[groupIndex.integerValue];
  88. TUIFaceGroup *face = _faceGroups[groupIndex.integerValue];
  89. NSInteger itemCount = face.rowCount * face.itemCountPerRow - face.needBackDelete;
  90. NSInteger groupSection = curSection - groupSectionIndex.integerValue;
  91. for (NSInteger itemIndex = 0; itemIndex < itemCount; ++itemIndex) {
  92. // transpose line/row
  93. NSInteger row = itemIndex % face.rowCount;
  94. NSInteger column = itemIndex / face.rowCount;
  95. NSInteger reIndex = face.itemCountPerRow * row + column + groupSection * itemCount;
  96. [_itemIndexs setObject:@(reIndex) forKey:[NSIndexPath indexPathForRow:itemIndex inSection:curSection]];
  97. }
  98. }
  99. _curGroupIndex = 0;
  100. if (_pageCountInGroup.count != 0) {
  101. _pageControl.numberOfPages = [_pageCountInGroup[0] intValue];
  102. }
  103. [_faceCollectionView reloadData];
  104. }
  105. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  106. return _sectionCount;
  107. }
  108. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  109. int groupIndex = [_groupIndexInSection[section] intValue];
  110. TUIFaceGroup *group = _faceGroups[groupIndex];
  111. return group.rowCount * group.itemCountPerRow;
  112. }
  113. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  114. TUIFaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:TFaceCell_ReuseId forIndexPath:indexPath];
  115. int groupIndex = [_groupIndexInSection[indexPath.section] intValue];
  116. TUIFaceGroup *group = _faceGroups[groupIndex];
  117. int itemCount = group.rowCount * group.itemCountPerRow;
  118. if (indexPath.row == itemCount - 1 && group.needBackDelete) {
  119. TUIFaceCellData *data = [[TUIFaceCellData alloc] init];
  120. data.path = TUIChatFaceImagePath(@"del_normal");
  121. [cell setData:data];
  122. cell.face.image = [cell.face.image rtl_imageFlippedForRightToLeftLayoutDirection];
  123. } else {
  124. NSNumber *index = [_itemIndexs objectForKey:indexPath];
  125. if (index.integerValue < group.faces.count) {
  126. TUIFaceCellData *data = group.faces[index.integerValue];
  127. [cell setData:data];
  128. } else {
  129. [cell setData:nil];
  130. }
  131. }
  132. return cell;
  133. }
  134. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  135. int groupIndex = [_groupIndexInSection[indexPath.section] intValue];
  136. TUIFaceGroup *faces = _faceGroups[groupIndex];
  137. int itemCount = faces.rowCount * faces.itemCountPerRow;
  138. if (indexPath.row == itemCount - 1 && faces.needBackDelete) {
  139. if (_delegate && [_delegate respondsToSelector:@selector(faceViewDidBackDelete:)]) {
  140. [_delegate faceViewDidBackDelete:self];
  141. }
  142. } else {
  143. NSNumber *index = [_itemIndexs objectForKey:indexPath];
  144. if (index.integerValue < faces.faces.count) {
  145. if (_delegate && [_delegate respondsToSelector:@selector(faceView:didSelectItemAtIndexPath:)]) {
  146. NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index.integerValue inSection:groupIndex];
  147. [_delegate faceView:self didSelectItemAtIndexPath:indexPath];
  148. }
  149. } else {
  150. }
  151. }
  152. }
  153. - (CGSize)collectionView:(UICollectionView *)collectionView
  154. layout:(UICollectionViewLayout *)collectionViewLayout
  155. sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  156. int groupIndex = [_groupIndexInSection[indexPath.section] intValue];
  157. TUIFaceGroup *group = _faceGroups[groupIndex];
  158. CGFloat width = (self.frame.size.width - TFaceView_Page_Padding * 2 - TFaceView_Margin * (group.itemCountPerRow - 1)) / group.itemCountPerRow;
  159. CGFloat height = (collectionView.frame.size.height - TFaceView_Margin * (group.rowCount - 1)) / group.rowCount;
  160. return CGSizeMake(width, height);
  161. }
  162. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  163. NSInteger curSection = round(scrollView.contentOffset.x / scrollView.frame.size.width);
  164. if (curSection >= _groupIndexInSection.count) {
  165. return;
  166. }
  167. NSNumber *groupIndex = _groupIndexInSection[curSection];
  168. NSNumber *startSection = _sectionIndexInGroup[groupIndex.integerValue];
  169. NSNumber *pageCount = _pageCountInGroup[groupIndex.integerValue];
  170. if (_curGroupIndex != groupIndex.integerValue) {
  171. _curGroupIndex = groupIndex.integerValue;
  172. _pageControl.numberOfPages = pageCount.integerValue;
  173. if (_delegate && [_delegate respondsToSelector:@selector(faceView:scrollToFaceGroupIndex:)]) {
  174. [_delegate faceView:self scrollToFaceGroupIndex:_curGroupIndex];
  175. }
  176. }
  177. _pageControl.currentPage = curSection - startSection.integerValue;
  178. }
  179. - (void)scrollToFaceGroupIndex:(NSInteger)index {
  180. if (index > _sectionIndexInGroup.count) {
  181. return;
  182. }
  183. NSNumber *start = _sectionIndexInGroup[index];
  184. NSNumber *count = _pageCountInGroup[index];
  185. NSInteger curSection = ceil(_faceCollectionView.contentOffset.x / _faceCollectionView.frame.size.width);
  186. if (curSection > start.integerValue && curSection < start.integerValue + count.integerValue) {
  187. return;
  188. }
  189. CGRect rect =
  190. CGRectMake(start.integerValue * _faceCollectionView.frame.size.width, 0, _faceCollectionView.frame.size.width, _faceCollectionView.frame.size.height);
  191. [_faceCollectionView scrollRectToVisible:rect animated:NO];
  192. [self scrollViewDidScroll:_faceCollectionView];
  193. }
  194. @end