LZBKeyBoardToolEmojiBar.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. //
  2. // LZBKeyBoardToolEmojiBar.m
  3. // LZBKeyBoardView
  4. //
  5. // Created by zibin on 16/12/6.
  6. // demo地址:https://github.com/lzbgithubcode/LZBKeyBoardView.git
  7. // Copyright © 2016年 apple. All rights reserved.
  8. //
  9. #import "LZBKeyBoardToolEmojiBar.h"
  10. #import "LZBTextView.h"
  11. #import "UIView+LZBViewFrame.h"
  12. #import "LZBFaceView.h"
  13. #import "NSString+LZBTranscoding.h"
  14. //颜色转换
  15. #define LZBColorRGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
  16. #define kKeyboardView_FaceViewHeight (216 + SafeHeight) // 表情键盘高度
  17. #define kKeyboardViewToolBarHeight 50 // 默认键盘输入工具条的高度
  18. #define kKeyboardViewToolBar_TextView_Height 35 // 默认键盘输入框的高度
  19. #define kKeyboardViewToolBar_TextView_LimitHeight 60 // 默认键盘输入框的限制高度
  20. #define kKeyboardViewToolBar_SendBtn_Width 40 // 默认发送按钮的宽度
  21. #define kKeyboardViewToolBar_Horizontal_DefaultMargin 15 //水平方向默认间距
  22. #define kKeyboardViewToolBar_Vertical_DefaultMargin 8 //垂直方向默认间距
  23. #define LZBScreenHeight [UIScreen mainScreen].bounds.size.height
  24. #define LZBScreenWidth [UIScreen mainScreen].bounds.size.width
  25. #define inputextViewFont [UIFont systemFontOfSize:14.0]
  26. @interface LZBKeyBoardToolEmojiBar()
  27. //View
  28. @property (nonatomic, strong) LZBTextView *inputTextView; //输入框
  29. @property (nonatomic, strong) UIView *topLine; // 顶部分割线
  30. @property (nonatomic, strong) UIView *bottomLine; // 底部分割线
  31. @property (nonatomic, strong) UIButton *faceButton; // 按钮
  32. @property (nonatomic, strong) LZBFaceView *faceView;
  33. @property (nonatomic, strong) UIView *inputBgV;
  34. //data
  35. @property (nonatomic, copy) void(^sendTextBlock)(NSString *text); //输入框输入字符串回调Blcok
  36. @property (nonatomic, assign) CGFloat textHeight; //输入文字高度
  37. @property (nonatomic, assign) CGFloat animationDuration; //动画时间
  38. @property (nonatomic, strong) NSString *placeHolder; //占位文字
  39. @end
  40. @implementation LZBKeyBoardToolEmojiBar
  41. #pragma mark - API
  42. + (LZBKeyBoardToolEmojiBar *)showKeyBoardWithConfigToolBarHeight:(CGFloat)toolBarHeight sendTextCompletion:(void(^)(NSString *sendText))sendTextBlock
  43. {
  44. LZBKeyBoardToolEmojiBar *toolBar = [[LZBKeyBoardToolEmojiBar alloc]init];
  45. toolBar.backgroundColor = HexColorFromRGB(0x2A2935);
  46. if(toolBarHeight < kKeyboardViewToolBarHeight)
  47. toolBarHeight = kKeyboardViewToolBarHeight;
  48. toolBar.frame = CGRectMake(0, LZBScreenHeight - toolBarHeight, LZBScreenWidth, toolBarHeight);
  49. toolBar.sendTextBlock = sendTextBlock;
  50. return toolBar;
  51. }
  52. - (void)setInputViewPlaceHolderText:(NSString *)placeText
  53. {
  54. self.inputTextView.placeholder = placeText;
  55. self.placeHolder = placeText;
  56. }
  57. - (void)becomeFirstResponder{
  58. [self.inputTextView becomeFirstResponder];
  59. self.hidden = NO;
  60. }
  61. - (void)resignFirstResponder{
  62. [self.inputTextView resignFirstResponder];
  63. }
  64. #pragma mark - private
  65. - (instancetype)initWithFrame:(CGRect)frame
  66. {
  67. if(self = [super initWithFrame:frame])
  68. {
  69. [self youpaifsetupUI];
  70. }
  71. return self;
  72. }
  73. - (void)youpaifsetupUI
  74. {
  75. UIView *inputBgV = [[UIView alloc] init];
  76. inputBgV.backgroundColor = [HexColorFromRGB(0x4F4B5B) colorWithAlphaComponent:0.43f];
  77. inputBgV.layer.cornerRadius = 17.5f;
  78. inputBgV.clipsToBounds = YES;
  79. [self addSubview:inputBgV];
  80. self.inputBgV = inputBgV;
  81. [self addSubview:self.inputTextView];
  82. [self addSubview:self.topLine];
  83. [self addSubview:self.bottomLine];
  84. [self addSubview:self.faceButton];
  85. @weakify(self);
  86. [self.faceView setEmojiModles:[self loadEmojiEmotions] selectEmojiModelBlock:^(LZBEmojiModel *selectModel) {
  87. @strongify(self);
  88. [self emojitionDidSelect:selectModel];
  89. } deleteBlcok:^{
  90. @strongify(self);
  91. [self emojitionDidDelete];
  92. } sendBlcok:^{
  93. @strongify(self);
  94. [self emojitionDidSend];
  95. }];
  96. [self.faceView setAnimationEmojiBtnClickBlock:^{
  97. @strongify(self);
  98. if (self.animationEmojiBtnClickBlock != nil) {
  99. self.animationEmojiBtnClickBlock();
  100. }
  101. }];
  102. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
  103. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self.inputTextView];
  104. }
  105. - (void)layoutSubviews
  106. {
  107. [super layoutSubviews];
  108. __weak typeof(self) weakSelf = self;
  109. CGFloat height = (self.textHeight + kKeyboardViewToolBar_TextView_Height)> kKeyboardViewToolBarHeight ? (self.textHeight + kKeyboardViewToolBar_TextView_Height) : kKeyboardViewToolBarHeight;
  110. CGFloat offsetY = self.LZB_heigth - height;
  111. [UIView animateWithDuration:self.animationDuration animations:^{
  112. weakSelf.LZB_y += offsetY;
  113. weakSelf.LZB_heigth = height;
  114. [LCTools clipCorner:UIRectCornerTopLeft|UIRectCornerTopRight View:weakSelf size:CGSizeMake(20.0f, 20.0f)];
  115. }];
  116. self.topLine.LZB_width = self.LZB_width;
  117. self.bottomLine.LZB_width = self.LZB_width;
  118. CGSize sendButtonSize = self.faceButton.currentImage.size;
  119. self.faceButton.LZB_width = sendButtonSize.width;
  120. self.faceButton.LZB_heigth = sendButtonSize.height;
  121. self.faceButton.LZB_x = self.LZB_width - sendButtonSize.width - kKeyboardViewToolBar_Horizontal_DefaultMargin;
  122. self.inputTextView.LZB_width = self.LZB_width - sendButtonSize.width - 3 *kKeyboardViewToolBar_Horizontal_DefaultMargin - 24.0f;
  123. self.inputTextView.LZB_x = kKeyboardViewToolBar_Horizontal_DefaultMargin + 12.0f;
  124. self.inputBgV.LZB_width = self.inputTextView.LZB_width + 24.0f;
  125. self.inputBgV.LZB_x = kKeyboardViewToolBar_Horizontal_DefaultMargin;
  126. [UIView animateWithDuration:self.animationDuration animations:^{
  127. weakSelf.inputTextView.LZB_heigth = weakSelf.LZB_heigth - 2 *kKeyboardViewToolBar_Vertical_DefaultMargin;
  128. weakSelf.inputTextView.LZB_centerY = weakSelf.LZB_heigth * 0.5;
  129. weakSelf.inputBgV.LZB_heigth = weakSelf.LZB_heigth - 2 *kKeyboardViewToolBar_Vertical_DefaultMargin;
  130. weakSelf.inputBgV.LZB_centerY = weakSelf.LZB_heigth * 0.5;
  131. weakSelf.faceButton.LZB_y = (weakSelf.LZB_heigth - sendButtonSize.height) / 2.0f;// - kKeyboardViewToolBar_Vertical_DefaultMargin;
  132. weakSelf.bottomLine.LZB_y = weakSelf.LZB_heigth - weakSelf.bottomLine.LZB_heigth;
  133. }];
  134. [self.inputTextView setNeedsUpdateConstraints];
  135. }
  136. #pragma mark - handle
  137. - (void)keyboardWillChangeFrame:(NSNotification *)notification
  138. {
  139. CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  140. CGFloat keyboardHeight = keyboardFrame.size.height;
  141. CGFloat keyboardAnimaitonDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  142. self.animationDuration = keyboardAnimaitonDuration;
  143. NSInteger option = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  144. // 普通文本键盘与表情键盘切换时,过滤
  145. BOOL isEmojiKeyBoard = !self.faceButton.selected &&keyboardFrame.size.height == kKeyboardView_FaceViewHeight;
  146. BOOL isNormalKeyBoard = self.faceButton.selected &&keyboardFrame.size.height != kKeyboardView_FaceViewHeight;
  147. if(isEmojiKeyBoard || isNormalKeyBoard) return;
  148. //判断键盘是否出现
  149. BOOL isKeyBoardHidden = LZBScreenHeight == keyboardFrame.origin.y;
  150. CGFloat offsetMarginY = isKeyBoardHidden ? LZBScreenHeight - self.LZB_heigth :LZBScreenHeight - self.LZB_heigth - keyboardHeight;
  151. [UIView animateKeyframesWithDuration:self.animationDuration delay:0 options:option animations:^{
  152. self.LZB_y = offsetMarginY;
  153. } completion:nil];
  154. }
  155. - (void)textDidChange
  156. {
  157. //注意:点击发送之后是先收到这个通知,收到通知的时候hasText = YES,让后再text = @"",所以在inputTextView里面的监听无效
  158. self.inputTextView.placeHolderHidden = self.inputTextView.hasText;
  159. if([self.inputTextView.text containsString:@"\n"])
  160. {
  161. [self emojitionDidSend];
  162. return;
  163. }
  164. CGFloat margin = self.inputTextView.textContainerInset.left + self.inputTextView.textContainerInset.right;
  165. CGFloat height = [self.inputTextView.text boundingRectWithSize:CGSizeMake(self.inputTextView.LZB_width - margin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.inputTextView.font} context:nil].size.height;
  166. if(height == self.textHeight) return;
  167. // 确保输入框不会无限增高,控制在显示4行
  168. if (height > kKeyboardViewToolBar_TextView_LimitHeight) {
  169. return;
  170. }
  171. self.textHeight = height;
  172. [self setNeedsLayout];
  173. }
  174. - (void)faceButtonClick:(UIButton *)faceButton
  175. {
  176. faceButton.selected = !faceButton.isSelected;
  177. self.bottomLine.hidden = !faceButton.selected;
  178. [self.inputTextView resignFirstResponder];
  179. self.inputTextView.inputView = faceButton.selected?self.faceView : nil;
  180. [self.inputTextView becomeFirstResponder];
  181. }
  182. - (void)showKeyBoard{
  183. self.faceButton.selected = YES;
  184. [self faceButtonClick:self.faceButton];
  185. }
  186. - (void)showEmoji{
  187. self.faceButton.selected = NO;
  188. [self faceButtonClick:self.faceButton];
  189. }
  190. - (void)emojitionDidSelect:(LZBEmojiModel *)emojiModel
  191. {
  192. self.inputTextView.text = [self.inputTextView.text stringByAppendingString:emojiModel.code.emoji];
  193. [self textDidChange];
  194. }
  195. - (void)emojitionDidDelete
  196. {
  197. [self.inputTextView deleteBackward];
  198. }
  199. - (void)emojitionDidSend
  200. {
  201. NSString *text = self.inputTextView.text;
  202. if(self.sendTextBlock)
  203. self.sendTextBlock(text);
  204. [self resetInputView];
  205. [self textDidChange];
  206. }
  207. - (void)resetInputView
  208. {
  209. self.inputTextView.text = @"";
  210. [self setInputViewPlaceHolderText:self.placeHolder.length > 0 ? self.placeHolder : @""];
  211. [self.inputTextView resignFirstResponder];
  212. if(self.faceButton.selected)
  213. {
  214. self.faceButton.selected = !self.faceButton.isSelected;
  215. self.bottomLine.hidden = !self.faceButton.selected;
  216. self.inputTextView.inputView = self.faceButton.selected?self.faceView : nil;
  217. }
  218. //布局的目的是布局textContainer 显示区域,显示区域回到初始位置
  219. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  220. [self setNeedsLayout];
  221. });
  222. }
  223. #pragma mark - lazy
  224. - (NSArray <LZBEmojiModel *>*)loadEmojiEmotions{
  225. NSString *path = [[NSBundle mainBundle] pathForResource:@"Resource.bundle/emoji.plist" ofType:nil];
  226. NSArray *emotions = [NSArray arrayWithContentsOfFile:path];
  227. NSMutableArray *emotionsMul = [NSMutableArray array];
  228. for (NSDictionary *dic in emotions) {
  229. LZBEmojiModel *model = [[LZBEmojiModel alloc] init];
  230. [model setValuesForKeysWithDictionary:dic];
  231. [emotionsMul addObject:model];
  232. }
  233. return emotionsMul.copy;
  234. }
  235. - (LZBFaceView *)faceView
  236. {
  237. if(_faceView == nil)
  238. {
  239. _faceView = [LZBFaceView new];
  240. _faceView.backgroundColor = HexColorFromRGB(0x2A2935);
  241. _faceView.frame = CGRectMake(0, 0, LZBScreenWidth, kKeyboardView_FaceViewHeight);
  242. }
  243. return _faceView;
  244. }
  245. - (UIButton *)faceButton
  246. {
  247. if(_faceButton == nil)
  248. {
  249. _faceButton = [UIButton buttonWithType:UIButtonTypeCustom];
  250. [_faceButton setImage:[UIImage imageNamed:@"vqu_images_chatroom_keyboard_emoji"] forState:UIControlStateNormal];
  251. [_faceButton setImage:[UIImage imageNamed:@"vqu_images_chatroom_keyboard"] forState:UIControlStateSelected];
  252. [_faceButton addTarget:self action:@selector(faceButtonClick:) forControlEvents:UIControlEventTouchUpInside];
  253. }
  254. return _faceButton;
  255. }
  256. - (LZBTextView *)inputTextView
  257. {
  258. if(_inputTextView == nil)
  259. {
  260. _inputTextView = [[LZBTextView alloc]init];
  261. _inputTextView.font = inputextViewFont;
  262. _inputTextView.textColor = [UIColor whiteColor];
  263. _inputTextView.tintColor = ZYPinkColor;
  264. _inputTextView.enablesReturnKeyAutomatically = YES;
  265. _inputTextView.returnKeyType = UIReturnKeySend;
  266. _inputTextView.placeholderColor = HexColorFromRGB(0x6C6B70);
  267. _inputTextView.backgroundColor = [UIColor clearColor];
  268. }
  269. return _inputTextView;
  270. }
  271. - (UIView *)topLine{
  272. if (_topLine == nil) {
  273. _topLine = [[UIView alloc] init];
  274. _topLine.LZB_heigth = 0.5;
  275. _topLine.backgroundColor = HexColorFromRGB(0x2A2935);
  276. }
  277. return _topLine;
  278. }
  279. - (UIView *)bottomLine{
  280. if (_bottomLine == nil) {
  281. _bottomLine = [[UIView alloc] init];
  282. _bottomLine.backgroundColor = HexColorFromRGB(0x4F4B5B);
  283. _bottomLine.LZB_heigth = 0.5;
  284. _bottomLine.hidden = YES;
  285. }
  286. return _bottomLine;
  287. }
  288. - (void)setIsCurrentUserUpSeat:(BOOL)isCurrentUserUpSeat{
  289. _isCurrentUserUpSeat = isCurrentUserUpSeat;
  290. self.faceView.isCurrentUserUpSeat = isCurrentUserUpSeat;
  291. }
  292. @end