DKUITableViewCell.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. //
  2. // DKUITableViewCell.m
  3. // chatandvideotest
  4. //
  5. // Created by Dongke on 15/11/18.
  6. // Copyright © 2015年 dongke. All rights reserved.
  7. //
  8. #import "DKUITableViewCell.h"
  9. static const CGFloat kDKLabelPadding = 5.0f;
  10. static const CGFloat kDKTimeStampLabelHeight = 20.0f;
  11. static const CGFloat kDKAvatarPaddingX = 8.0;
  12. static const CGFloat kDKAvatarPaddingY = 15;
  13. static const CGFloat kDKUserNameLabelHeight = 20;
  14. @interface DKUITableViewCell () {
  15. }
  16. @property (nonatomic, weak, readwrite) DKMessageBubbleView *messageBubbleView;
  17. /**
  18. * 是否显示时间轴Label
  19. */
  20. @property (nonatomic, assign) BOOL displayTimestamp;
  21. /**
  22. * 1、是否显示Time Line的label
  23. *
  24. * @param message 需要配置的目标消息Model
  25. */
  26. //- (void)configureTimestamp:(BOOL)displayTimestamp atMessage:(id <DKMessageModel>)message;
  27. /**
  28. * 3、配置需要显示什么消息内容,比如语音、文字、视频、图片
  29. *
  30. * @param message 需要配置的目标消息Model
  31. */
  32. - (void)configureMessageBubbleViewWithMessage:(id <DKMessageModel>)message;
  33. /**
  34. * 统一一个方法隐藏MenuController,多处需要调用
  35. */
  36. - (void)setupNormalMenuController;
  37. /**
  38. * 点击Cell的手势处理方法,用于隐藏MenuController的
  39. *
  40. * @param tapGestureRecognizer 点击手势对象
  41. */
  42. - (void)tapGestureRecognizerHandle:(UITapGestureRecognizer *)tapGestureRecognizer;
  43. /**
  44. * 单击手势处理方法,用于点击多媒体消息触发方法,比如点击语音需要播放的回调、点击图片需要查看大图的回调
  45. *
  46. * @param tapGestureRecognizer 点击手势对象
  47. */
  48. - (void)sigleTapGestureRecognizerHandle:(UITapGestureRecognizer *)tapGestureRecognizer;
  49. @end
  50. @implementation DKUITableViewCell
  51. - (void)configureCellWithMessage:(id <DKMessageModel>)message
  52. displaysTimestamp:(BOOL)displayTimestamp {
  53. // 4、配置需要显示什么消息内容,比如语音、文字、视频、图片
  54. [self configureMessageBubbleViewWithMessage:message];
  55. }
  56. - (void)configureMessageBubbleViewWithMessage:(id <DKMessageModel>)message {
  57. DKBubbleMessageMediaType currentMediaType = message.messageMediaType;
  58. for (UIGestureRecognizer *gesTureRecognizer in self.messageBubbleView.bubbleImageView.gestureRecognizers) {
  59. [self.messageBubbleView.bubbleImageView removeGestureRecognizer:gesTureRecognizer];
  60. }
  61. // for (UIGestureRecognizer *gesTureRecognizer in self.messageBubbleView.bubblePhotoImageView.gestureRecognizers) {
  62. // [self.messageBubbleView.bubblePhotoImageView removeGestureRecognizer:gesTureRecognizer];
  63. // }
  64. switch (currentMediaType) {
  65. case DKBubbleMessageMediaTypePhoto:
  66. case DKBubbleMessageMediaTypeVideo:
  67. case DKBubbleMessageMediaTypeLocalPosition: {
  68. // UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sigleTapGestureRecognizerHandle:)];
  69. // [self.messageBubbleView.bubblePhotoImageView addGestureRecognizer:tapGestureRecognizer];
  70. break;
  71. }
  72. case DKBubbleMessageMediaTypeText:
  73. case DKBubbleMessageMediaTypeVoice:
  74. case DKBubbleMessageMediaTypeEmotion: {
  75. UITapGestureRecognizer *tapGestureRecognizer;
  76. if (currentMediaType == DKBubbleMessageMediaTypeText) {
  77. //tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGestureRecognizerHandle:)];
  78. } else {
  79. tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sigleTapGestureRecognizerHandle:)];
  80. }
  81. tapGestureRecognizer.numberOfTapsRequired = (currentMediaType == DKBubbleMessageMediaTypeText ? 2 : 1);
  82. [self.messageBubbleView.bubbleImageView addGestureRecognizer:tapGestureRecognizer];
  83. break;
  84. }
  85. default:
  86. break;
  87. }
  88. [self.messageBubbleView configureCellWithMessage:message];
  89. }
  90. #pragma mark - Copying Method
  91. - (BOOL)canBecomeFirstResponder {
  92. return YES;
  93. }
  94. - (BOOL)becomeFirstResponder {
  95. return [super becomeFirstResponder];
  96. }
  97. //- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
  98. //// return (action == @selector(copyed:) || action == @selector(transpond:) || action == @selector(favorites:) || action == @selector(more:));
  99. //}
  100. #pragma mark - Gestures
  101. - (void)setupNormalMenuController {
  102. UIMenuController *menu = [UIMenuController sharedMenuController];
  103. if (menu.isMenuVisible) {
  104. [menu setMenuVisible:NO animated:YES];
  105. }
  106. }
  107. - (void)tapGestureRecognizerHandle:(UITapGestureRecognizer *)tapGestureRecognizer {
  108. [self updateMenuControllerVisiable];
  109. }
  110. - (void)updateMenuControllerVisiable {
  111. [self setupNormalMenuController];
  112. }
  113. - (void)sigleTapGestureRecognizerHandle:(UITapGestureRecognizer *)tapGestureRecognizer {
  114. if (tapGestureRecognizer.state == UIGestureRecognizerStateEnded) {
  115. [self setupNormalMenuController];
  116. if ([self.delegate respondsToSelector:@selector(multiMediaMessageDidSelectedOnMessage:atIndexPath:onMessageTableViewCell:)]) {
  117. [self.delegate multiMediaMessageDidSelectedOnMessage:self.messageBubbleView.message atIndexPath:self.indexPath onMessageTableViewCell:self];
  118. }
  119. }
  120. }
  121. #pragma mark - Notifications
  122. - (void)handleMenuWillHideNotification:(NSNotification *)notification {
  123. [[NSNotificationCenter defaultCenter] removeObserver:self
  124. name:UIMenuControllerWillHideMenuNotification
  125. object:nil];
  126. }
  127. - (void)handleMenuWillShowNotification:(NSNotification *)notification {
  128. [[NSNotificationCenter defaultCenter] removeObserver:self
  129. name:UIMenuControllerWillShowMenuNotification
  130. object:nil];
  131. [[NSNotificationCenter defaultCenter] addObserver:self
  132. selector:@selector(handleMenuWillHideNotification:)
  133. name:UIMenuControllerWillHideMenuNotification
  134. object:nil];
  135. }
  136. - (void)dealloc {
  137. _messageBubbleView = nil;
  138. _indexPath = nil;
  139. [[NSNotificationCenter defaultCenter] removeObserver:self];
  140. }
  141. - (DKBubbleMessageType)bubbleMessageType {
  142. return self.messageBubbleView.message.bubbleMessageType;
  143. }
  144. + (CGFloat)calculateCellHeightWithMessage:(id <DKMessageModel>)message
  145. displaysTimestamp:(BOOL)displayTimestamp {
  146. // 第一,是否有时间戳的显示
  147. CGFloat timestampHeight = displayTimestamp ? (kDKTimeStampLabelHeight + kDKLabelPadding * 2) : 0;
  148. CGFloat userInfoNeedHeight = kDKAvatarPaddingY + (message.shouldShowUserName ? kDKUserNameLabelHeight : 0) + kDKAvatarPaddingY + timestampHeight;
  149. CGFloat bubbleMessageHeight = [DKMessageBubbleView calculateCellHeightWithMessage:message] + timestampHeight;
  150. return MAX(bubbleMessageHeight, userInfoNeedHeight);
  151. }
  152. #pragma mark - Life cycle
  153. - (void)setup {
  154. self.backgroundColor = [UIColor clearColor];
  155. self.selectionStyle = UITableViewCellSelectionStyleNone;
  156. self.accessoryType = UITableViewCellAccessoryNone;
  157. self.accessoryView = nil;
  158. // UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognizerHandle:)];
  159. // [recognizer setMinimumPressDuration:0.4f];
  160. // [self addGestureRecognizer:recognizer];
  161. UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognizerHandle:)];
  162. [self addGestureRecognizer:tapGestureRecognizer];
  163. }
  164. - (instancetype)initWithMessage:(id <DKMessageModel>)message
  165. displaysTimestamp:(BOOL)displayTimestamp
  166. reuseIdentifier:(NSString *)cellIdentifier {
  167. self = [self initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
  168. if (self) {
  169. // 如果初始化成功,那就根据Message类型进行初始化控件,比如配置头像,配置发送和接收的样式
  170. // 1、是否显示Time Line的label
  171. // 2、配置头像
  172. // 3、配置用户名
  173. // 4、配置需要显示什么消息内容,比如语音、文字、视频、图片
  174. if (!_messageBubbleView) {
  175. // bubble container
  176. DKMessageBubbleView *messageBubbleView = [[DKMessageBubbleView alloc] initWithFrame:CGRectZero message:message];
  177. [self.contentView addSubview:messageBubbleView];
  178. [self.contentView sendSubviewToBack:messageBubbleView];
  179. self.messageBubbleView = messageBubbleView;
  180. }
  181. }
  182. return self;
  183. }
  184. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  185. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  186. if (self) {
  187. // Initialization code
  188. [self setup];
  189. }
  190. return self;
  191. }
  192. - (void)awakeFromNib {
  193. // Initialization code
  194. [super awakeFromNib];
  195. [self setup];
  196. }
  197. - (void)layoutSubviews {
  198. [super layoutSubviews];
  199. // // 布局头像
  200. // CGFloat layoutOriginY = kDKAvatarPaddingY + (self.displayTimestamp ? kDKTimeStampLabelHeight : 0);
  201. // 布局用户名
  202. // 布局消息内容的View
  203. CGFloat bubbleX = 0.0f;
  204. CGFloat offsetX = 0.0f;
  205. if ([self bubbleMessageType] == DKBubbleMessageTypeReceiving) {
  206. bubbleX = kDKAvatarPaddingX * 2;
  207. } else {
  208. offsetX = kDKAvatarPaddingX * 2;
  209. }
  210. CGFloat timeStampLabelNeedHeight = (self.displayTimestamp ? (kDKTimeStampLabelHeight + kDKLabelPadding) : 0);
  211. CGRect bubbleMessageViewFrame = CGRectMake(bubbleX,
  212. timeStampLabelNeedHeight,
  213. CGRectGetWidth(self.contentView.bounds) - bubbleX - offsetX,
  214. CGRectGetHeight(self.contentView.bounds) - timeStampLabelNeedHeight);
  215. self.messageBubbleView.frame = bubbleMessageViewFrame;
  216. }
  217. #pragma mark - TableViewCell
  218. - (void)prepareForReuse {
  219. // 这里做清除工作
  220. [super prepareForReuse];
  221. // self.messageBubbleView.displayTextView.text = nil;
  222. // self.messageBubbleView.displayTextView.attributedText = nil;
  223. self.messageBubbleView.bubbleImageView.image = nil;
  224. //self.messageBubbleView.emotionImageView.animatedImage = nil;
  225. self.messageBubbleView.animationVoiceImageView.image = nil;
  226. self.messageBubbleView.voiceDurationLabel.text = nil;
  227. // self.messageBubbleView.bubblePhotoImageView.messagePhoto = nil;
  228. //self.messageBubbleView.geolocationsLabel.text = nil;
  229. }
  230. @end