YOUPAINIMInputEmoticonContainerView.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. //
  2. // YOUPAINIMInputEmoticonContainerView.m
  3. // NIMKit
  4. //
  5. // Created by chris.
  6. // Copyright (c) 2015年 NetEase. All rights reserved.
  7. //
  8. #import "YOUPAINIMInputEmoticonContainerView.h"
  9. #import "NIMPageView.h"
  10. #import "UIView+NIM.h"
  11. #import "YOUPAINIMInputEmoticonButton.h"
  12. #import "YOUPAINIMInputEmoticonManager.h"
  13. #import "YOUPAINIMInputEmoticonTabView.h"
  14. #import "NIMInputEmoticonDefine.h"
  15. #import "UIImage+NIMKit.h"
  16. NSInteger NIMCustomPageControlHeight = 36;
  17. NSInteger NIMCustomPageViewHeight = 159;
  18. @interface YOUPAINIMInputEmoticonContainerView()<NIMEmoticonButtonTouchDelegate,NIMInputEmoticonTabDelegate>
  19. @property (nonatomic,strong) NSMutableArray *pageData;
  20. @end
  21. @implementation YOUPAINIMInputEmoticonContainerView
  22. - (instancetype)initWithFrame:(CGRect)frame
  23. {
  24. if (self = [super initWithFrame:frame]) {
  25. self.backgroundColor = LCBkgColor;
  26. [self loadConfig];
  27. }
  28. return self;
  29. }
  30. - (void)loadConfig{
  31. self.backgroundColor = [UIColor clearColor];
  32. }
  33. - (void)setConfig:(id<NIMSessionConfig>)config{
  34. _config = config;
  35. [self loadUIComponents];
  36. [self reloadData];
  37. }
  38. - (CGSize)sizeThatFits:(CGSize)size
  39. {
  40. return CGSizeMake(size.width, 216.f);
  41. }
  42. - (void)loadUIComponents
  43. {
  44. _emoticonPageView = [[NIMPageView alloc] initWithFrame:self.bounds];
  45. _emoticonPageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  46. _emoticonPageView.nim_height = NIMCustomPageViewHeight;
  47. _emoticonPageView.backgroundColor = [UIColor clearColor];
  48. _emoticonPageView.dataSource = self;
  49. _emoticonPageView.pageViewDelegate = self;
  50. [self addSubview:_emoticonPageView];
  51. _emotPageController = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, self.nim_width, NIMCustomPageControlHeight)];
  52. _emotPageController.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  53. _emotPageController.pageIndicatorTintColor = [UIColor lightGrayColor];
  54. _emotPageController.currentPageIndicatorTintColor = [UIColor grayColor];
  55. [self addSubview:_emotPageController];
  56. [_emotPageController setUserInteractionEnabled:NO];
  57. }
  58. - (void)setFrame:(CGRect)frame{
  59. CGFloat originalWidth = self.frame.size.width;
  60. [super setFrame:frame];
  61. if (originalWidth != frame.size.width) {
  62. [self reloadData];
  63. }
  64. }
  65. - (void)reloadData{
  66. NSArray *data = [self loadCatalogAndChartlet];
  67. self.totalCatalogData = data;
  68. self.currentCatalogData = data.firstObject;
  69. }
  70. - (NSArray *)loadCatalogAndChartlet
  71. {
  72. NIMInputEmoticonCatalog * defaultCatalog = [self loadDefaultCatalog];
  73. NSArray *charlets = [self loadChartlet];
  74. NSArray *catalogs = defaultCatalog? [@[defaultCatalog] arrayByAddingObjectsFromArray:charlets] : charlets;
  75. return catalogs;
  76. }
  77. #define EmotPageControllerMarginBottom 10
  78. - (void)layoutSubviews{
  79. [super layoutSubviews];
  80. self.emotPageController.nim_top = self.emoticonPageView.nim_bottom - EmotPageControllerMarginBottom;
  81. self.tabView.nim_bottom = self.nim_height;
  82. }
  83. #pragma mark - config data
  84. - (NSInteger)sumPages
  85. {
  86. __block NSInteger pagesCount = 0;
  87. [self.totalCatalogData enumerateObjectsUsingBlock:^(NIMInputEmoticonCatalog* data, NSUInteger idx, BOOL *stop) {
  88. pagesCount += data.pagesCount;
  89. }];
  90. return pagesCount;
  91. }
  92. - (UIView*)emojPageView:(NIMPageView*)pageView inEmoticonCatalog:(NIMInputEmoticonCatalog *)emoticon page:(NSInteger)page
  93. {
  94. UIView *subView = [[UIView alloc] init];
  95. NSInteger iconHeight = emoticon.layout.imageHeight;
  96. NSInteger iconWidth = emoticon.layout.imageWidth;
  97. CGFloat startX = (emoticon.layout.cellWidth - iconWidth) / 2 + NIMKit_EmojiLeftMargin;
  98. CGFloat startY = (emoticon.layout.cellHeight- iconHeight) / 2 + NIMKit_EmojiTopMargin;
  99. int32_t coloumnIndex = 0;
  100. int32_t rowIndex = 0;
  101. int32_t indexInPage = 0;
  102. NSInteger begin = page * emoticon.layout.itemCountInPage;
  103. NSInteger end = begin + emoticon.layout.itemCountInPage;
  104. end = end > emoticon.emoticons.count ? (emoticon.emoticons.count) : end;
  105. for (NSInteger index = begin; index < end; index ++)
  106. {
  107. NIMInputEmoticon *data = [emoticon.emoticons objectAtIndex:index];
  108. YOUPAINIMInputEmoticonButton *button = [YOUPAINIMInputEmoticonButton youpaificonButtonWithData:data catalogID:emoticon.catalogID delegate:self];
  109. //计算表情位置
  110. rowIndex = indexInPage / emoticon.layout.columes;
  111. coloumnIndex= indexInPage % emoticon.layout.columes;
  112. CGFloat x = coloumnIndex * emoticon.layout.cellWidth + startX;
  113. CGFloat y = rowIndex * emoticon.layout.cellHeight + startY;
  114. CGRect iconRect = CGRectMake(x, y, iconWidth, iconHeight);
  115. [button setFrame:iconRect];
  116. [subView addSubview:button];
  117. indexInPage ++;
  118. }
  119. if (coloumnIndex == emoticon.layout.columes -1)
  120. {
  121. rowIndex = rowIndex +1;
  122. coloumnIndex = -1; //设置成-1是因为显示在第0位,有加1
  123. }
  124. if ([emoticon.catalogID isEqualToString:NIMKit_EmojiCatalog]) {
  125. [self addDeleteEmotButtonToView:subView ColumnIndex:coloumnIndex RowIndex:rowIndex StartX:startX StartY:startY IconWidth:iconWidth IconHeight:iconHeight inEmoticonCatalog:emoticon];
  126. }
  127. return subView;
  128. }
  129. - (void)addDeleteEmotButtonToView:(UIView *)view
  130. ColumnIndex:(NSInteger)coloumnIndex
  131. RowIndex:(NSInteger)rowIndex
  132. StartX:(CGFloat)startX
  133. StartY:(CGFloat)startY
  134. IconWidth:(CGFloat)iconWidth
  135. IconHeight:(CGFloat)iconHeight
  136. inEmoticonCatalog:(NIMInputEmoticonCatalog *)emoticon
  137. {
  138. YOUPAINIMInputEmoticonButton* deleteIcon = [[YOUPAINIMInputEmoticonButton alloc] init];
  139. deleteIcon.delegate = self;
  140. deleteIcon.userInteractionEnabled = YES;
  141. deleteIcon.exclusiveTouch = YES;
  142. deleteIcon.contentMode = UIViewContentModeCenter;
  143. NSString *prefix = NIMKit_EmojiPath;
  144. NSString *imageNormalName = [prefix stringByAppendingPathComponent:@"emoji_del_normal"];
  145. NSString *imagePressName = [prefix stringByAppendingPathComponent:@"emoji_del_pressed"];
  146. UIImage *imageNormal = [UIImage nim_emoticonInKit:imageNormalName];
  147. UIImage *imagePressed = [UIImage nim_emoticonInKit:imagePressName];
  148. [deleteIcon setImage:imageNormal forState:UIControlStateNormal];
  149. [deleteIcon setImage:imagePressed forState:UIControlStateHighlighted];
  150. [deleteIcon addTarget:deleteIcon action:@selector(youpaifonIconSelected:) forControlEvents:UIControlEventTouchUpInside];
  151. CGFloat newX = (coloumnIndex +1) * emoticon.layout.cellWidth + startX;
  152. CGFloat newY = rowIndex * emoticon.layout.cellHeight + startY;
  153. CGRect deleteIconRect = CGRectMake(newX, newY, NIMKit_DeleteIconWidth, NIMKit_DeleteIconHeight);
  154. [deleteIcon setFrame:deleteIconRect];
  155. [view addSubview:deleteIcon];
  156. }
  157. #pragma mark - pageviewDelegate
  158. - (NSInteger)numberOfPages: (NIMPageView *)pageView
  159. {
  160. return [self sumPages];
  161. }
  162. - (UIView *)pageView:(NIMPageView *)pageView viewInPage:(NSInteger)index
  163. {
  164. NSInteger page = 0;
  165. NIMInputEmoticonCatalog *emoticon;
  166. for (emoticon in self.totalCatalogData) {
  167. NSInteger newPage = page + emoticon.pagesCount;
  168. if (newPage > index) {
  169. break;
  170. }
  171. page = newPage;
  172. }
  173. return [self emojPageView:pageView inEmoticonCatalog:emoticon page:index - page];
  174. }
  175. - (NIMInputEmoticonCatalog*)loadDefaultCatalog
  176. {
  177. NIMInputEmoticonCatalog *youpaifemoticonCatalog = [[YOUPAINIMInputEmoticonManager sharedManager] youpaifemoticonCatalog:NIMKit_EmojiCatalog];
  178. if (youpaifemoticonCatalog) {
  179. NIMInputEmoticonLayout *layout = [[NIMInputEmoticonLayout alloc] initEmojiLayout:self.nim_width];
  180. youpaifemoticonCatalog.layout = layout;
  181. youpaifemoticonCatalog.pagesCount = [self numberOfPagesWithEmoticon:youpaifemoticonCatalog];
  182. }
  183. return youpaifemoticonCatalog;
  184. }
  185. - (NSArray *)loadChartlet{
  186. NSArray *chatlets = nil;
  187. if ([self.config respondsToSelector:@selector(charlets)])
  188. {
  189. chatlets = [self.config charlets];
  190. for (NIMInputEmoticonCatalog *item in chatlets) {
  191. NIMInputEmoticonLayout *layout = [[NIMInputEmoticonLayout alloc] initCharletLayout:self.nim_width];
  192. item.layout = layout;
  193. item.pagesCount = [self numberOfPagesWithEmoticon:item];
  194. }
  195. }
  196. return chatlets;
  197. }
  198. //找到某组表情的起始位置
  199. - (NSInteger)pageIndexWithEmoticon:(NIMInputEmoticonCatalog *)youpaifemoticonCatalog{
  200. NSInteger pageIndex = 0;
  201. for (NIMInputEmoticonCatalog *emoticon in self.totalCatalogData) {
  202. if (emoticon == youpaifemoticonCatalog) {
  203. break;
  204. }
  205. pageIndex += emoticon.pagesCount;
  206. }
  207. return pageIndex;
  208. }
  209. - (NSInteger)pageIndexWithTotalIndex:(NSInteger)index{
  210. NIMInputEmoticonCatalog *catelog = [self emoticonWithIndex:index];
  211. NSInteger begin = [self pageIndexWithEmoticon:catelog];
  212. return index - begin;
  213. }
  214. - (NIMInputEmoticonCatalog *)emoticonWithIndex:(NSInteger)index {
  215. NSInteger page = 0;
  216. NIMInputEmoticonCatalog *emoticon;
  217. for (emoticon in self.totalCatalogData) {
  218. NSInteger newPage = page + emoticon.pagesCount;
  219. if (newPage > index) {
  220. break;
  221. }
  222. page = newPage;
  223. }
  224. return emoticon;
  225. }
  226. - (NSInteger)numberOfPagesWithEmoticon:(NIMInputEmoticonCatalog *)youpaifemoticonCatalog
  227. {
  228. if(youpaifemoticonCatalog.emoticons.count % youpaifemoticonCatalog.layout.itemCountInPage == 0)
  229. {
  230. return youpaifemoticonCatalog.emoticons.count / youpaifemoticonCatalog.layout.itemCountInPage;
  231. }
  232. else
  233. {
  234. return youpaifemoticonCatalog.emoticons.count / youpaifemoticonCatalog.layout.itemCountInPage + 1;
  235. }
  236. }
  237. - (void)pageViewScrollEnd: (NIMPageView *)pageView
  238. currentIndex: (NSInteger)index
  239. totolPages: (NSInteger)pages{
  240. NIMInputEmoticonCatalog *emticon = [self emoticonWithIndex:index];
  241. self.emotPageController.numberOfPages = [emticon pagesCount];
  242. self.emotPageController.currentPage = [self pageIndexWithTotalIndex:index];
  243. NSInteger youpaifselectTabIndex = [self.totalCatalogData indexOfObject:emticon];
  244. [self.tabView youpaifselectTabIndex:youpaifselectTabIndex];
  245. }
  246. #pragma mark - EmoticonButtonTouchDelegate
  247. - (void)selectedEmoticon:(NIMInputEmoticon*)emoticon catalogID:(NSString*)catalogID{
  248. if ([self.delegate respondsToSelector:@selector(selectedEmoticon:catalog:description:)]) {
  249. [self.delegate selectedEmoticon:emoticon.emoticonID catalog:catalogID description:emoticon.tag];
  250. }
  251. }
  252. - (void)youpaifdidPressSend:(id)sender{
  253. if ([self.delegate respondsToSelector:@selector(youpaifdidPressSend:)]) {
  254. [self.delegate youpaifdidPressSend:sender];
  255. }
  256. }
  257. #pragma mark - InputEmoticonTabDelegate
  258. - (void)tabView:(YOUPAINIMInputEmoticonTabView *)tabView didSelectTabIndex:(NSInteger) index{
  259. self.currentCatalogData = self.totalCatalogData[index];
  260. }
  261. #pragma mark - Private
  262. - (void)setCurrentCatalogData:(NIMInputEmoticonCatalog *)currentCatalogData{
  263. _currentCatalogData = currentCatalogData;
  264. [self.emoticonPageView scrollToPage:[self pageIndexWithEmoticon:_currentCatalogData]];
  265. }
  266. - (void)setTotalCatalogData:(NSArray *)totalCatalogData
  267. {
  268. _totalCatalogData = totalCatalogData;
  269. [self.tabView youpaifloadCatalogs:totalCatalogData];
  270. }
  271. - (NSArray *)allEmoticons{
  272. NSMutableArray *array = [[NSMutableArray alloc] init];
  273. for (NIMInputEmoticonCatalog *catalog in self.totalCatalogData) {
  274. [array addObjectsFromArray:catalog.emoticons];
  275. }
  276. return array;
  277. }
  278. #pragma mark - Get
  279. - (YOUPAINIMInputEmoticonTabView *)tabView
  280. {
  281. if (!_tabView) {
  282. _tabView = [[YOUPAINIMInputEmoticonTabView alloc] initWithFrame:CGRectMake(0, 0, self.nim_width, 0)];
  283. _tabView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  284. _tabView.delegate = self;
  285. [_tabView.sendButton addTarget:self action:@selector(youpaifdidPressSend:) forControlEvents:UIControlEventTouchUpInside];
  286. [self addSubview:_tabView];
  287. if (_currentCatalogData.pagesCount > 0) {
  288. _emotPageController.numberOfPages = [_currentCatalogData pagesCount];
  289. _emotPageController.currentPage = 0;
  290. }
  291. }
  292. return _tabView;
  293. }
  294. @end