[iOS基础控件 - 6.9] 聊天界面Demo
- 自定义message模型
- 自定义cell
- 装载了message模型和cell子控件位置尺寸的frame
1 @implementation NSString (Extension) 2 3 /** 测量文本的尺寸 */ 4 - (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize { 5 NSDictionary *attrs = @{NSFontAttributeName: font}; 6 CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; 7 8 return size; 9 } 10 11 @end
1 // 3.信息,尺寸可变 2 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 3 // 3.1 设置最大尺寸 4 CGSize textMaxSize = CGSizeMake(screenWidth - iconWidth - padding * 5, MAXFLOAT); 5 // 3.2 计算真实尺寸 6 CGSize textRealSize = [message.text sizeWithFont:MESSAGE_TEXT_FONT maxSize:textMaxSize]; 7 8 // 3.3 调整信息的位置 9 CGFloat textX; 10 if (MessageTypeMe == message.type) { 11 // 我方,放在靠右 12 textX = CGRectGetMinX(_iconFrame) - textRealSize.width - padding; 13 } else { 14 // 对方,放在靠左 15 textX = CGRectGetMaxX(_iconFrame) + padding; 16 } 17 18 CGFloat textY = iconY; 19 _textFrame = CGRectMake(textX, textY, textRealSize.width, textRealSize.height);
1 // 2.头像 2 CGFloat iconWidth = 40; 3 CGFloat iconHeight = 40; 4 5 // 2.1 根据信息的发送方调整头像位置 6 CGFloat iconX; 7 if (MessageTypeMe == message.type) { 8 // 我方,放在右边 9 iconX = [UIScreen mainScreen].bounds.size.width - padding - iconWidth; 10 } else { 11 // 对方,放在左边 12 iconX = padding; 13 } 14 15 CGFloat iconY = CGRectGetMaxY(_timeFrame) + padding; 16 _iconFrame = CGRectMake(iconX, iconY, iconWidth, iconHeight);
1 @implementation UIImage (Extension) 2 3 + (UIImage *) resizableImage:(NSString *) imageName { 4 UIImage *image = [UIImage imageNamed:imageName]; 5 // 取图片中部的1 x 1进行拉伸 6 UIEdgeInsets insets = UIEdgeInsetsMake(image.size.height/2, image.size.width/2, image.size.height/2 + 1, image.size.width/2 + 1); 7 return [image resizableImageWithCapInsets:insets]; 8 } 9 10 @end
1 // 3.1 设置聊天框 2 NSString *chatImageNormalName; 3 NSString *chatImageHighlightedName; 4 if (MessageTypeMe == messageFrame.message.type) { 5 chatImageNormalName = @"chat_send_nor"; 6 chatImageHighlightedName = @"chat_send_press_pic"; 7 } else { 8 chatImageNormalName = @"chat_receive_nor"; 9 chatImageHighlightedName = @"chat_receive_press_pic"; 10 } 11 12 UIImage *chatImageNormal = [UIImage resizableImage:chatImageNormalName]; 13 UIImage *chatImageHighlighted = [UIImage resizableImage:chatImageHighlightedName]; 14 [self.textView setBackgroundImage:chatImageNormal forState:UIControlStateNormal]; 15 [self.textView setBackgroundImage:chatImageHighlighted forState:UIControlStateHighlighted];
1 // 3.2 调整文字的内边距 2 textView.contentEdgeInsets = UIEdgeInsetsMake(TEXT_INSET, TEXT_INSET, TEXT_INSET, TEXT_INSET);
1 // 3.信息,尺寸可变 2 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 3 // 3.1 设置文本最大尺寸 4 CGSize textMaxSize = CGSizeMake(screenWidth - iconWidth - padding * 10, MAXFLOAT); 5 // 3.2 计算文本真实尺寸 6 CGSize textRealSize = [message.text sizeWithFont:MESSAGE_TEXT_FONT maxSize:textMaxSize]; 7 8 // 3.3 按钮尺寸 9 CGSize btnSize = CGSizeMake(textRealSize.width + TEXT_INSET*2, textRealSize.height + TEXT_INSET*2); 10 11 // 3.4 调整信息的位置 12 CGFloat textX; 13 if (MessageTypeMe == message.type) { 14 // 我方,放在靠右 15 textX = CGRectGetMinX(_iconFrame) - btnSize.width - padding; 16 } else { 17 // 对方,放在靠左 18 textX = CGRectGetMaxX(_iconFrame) + padding; 19 } 20 21 CGFloat textY = iconY; 22 _textFrame = CGRectMake(textX, textY, btnSize.width, btnSize.height);
1 /** 是否隐藏发送时间 */ 2 @property(nonatomic, assign) BOOL hideTime;
1 // 判断是否发送时间与上一条信息的发送时间相同,若是则不用显示了 2 MessageFrame *lastMessageFrame = [mdictArray lastObject]; 3 if (lastMessageFrame && [message.time isEqualToString:lastMessageFrame.message.time]) { 4 message.hideTime = YES; 5 }
1 // 1.发送时间 2 if (NO == message.hideTime) { 3 CGFloat timeWidth = [UIScreen mainScreen].bounds.size.width; 4 CGFloat timeHeight = 40; 5 CGFloat timeX = 0; 6 CGFloat timeY = 0; 7 _timeFrame = CGRectMake(timeX, timeY, timeWidth, timeHeight); 8 }
1 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
1 /** 点击拖曳聊天区的时候,缩回键盘 */ 2 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 3 // 1.缩回键盘 4 [self.view endEditing:YES]; 5 } 6 7 8 #pragma mark - 监听事件 9 - (void) keyboardWillChangeFrame:(NSNotification *) note { 10 // 1.取得弹出后的键盘frame 11 CGRect keyboardFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 12 13 // 2.键盘弹出的耗时时间 14 CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; 15 16 // 3.键盘变化时,view的位移,包括了上移/恢复下移 17 CGFloat transformY = keyboardFrame.origin.y - self.view.frame.size.height; 18 19 [UIView animateWithDuration:duration animations:^{ 20 self.view.transform = CGAffineTransformMakeTranslation(0, transformY); 21 }]; 22 23 24 }
1 // 设置信息输入框的代理 2 self.inputView.delegate = self;
1 #pragma mark - TextField 代理方法 2 /** 回车响应事件 */ 3 - (BOOL)textFieldShouldReturn:(UITextField *)textField { 4 // 我方发出信息 5 [self sendMessageWithContent:textField.text andType:MessageTypeMe]; 6 7 // 自动回复 8 [self sendMessageWithContent:[NSString stringWithFormat:@"%@\n%@", textField.text, @"你妹!!!"] andType:MessageTypeOhter]; 9 10 // 消除消息框内容 11 self.inputView.text = nil; 12 13 [self.tableView reloadData]; 14 15 // 滚动到最新的消息 16 NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0]; 17 [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 18 19 return YES; // 返回值意义不明 20 } 21 22 // 发送消息 23 - (void) sendMessageWithContent:(NSString *) text andType:(MessageType) type { 24 // 获取当前时间 25 NSDate *date = [NSDate date]; 26 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 27 formatter.dateFormat = @"yyyy-MMM-dd hh:mm:ss"; 28 NSString *dateStr = [formatter stringFromDate:date]; 29 30 // 我方发出信息 31 NSDictionary *dict = @{@"text":text, 32 @"time":dateStr, 33 @"type":[NSString stringWithFormat:@"%d", type]}; 34 35 Message *message = [[Message alloc] init]; 36 [message setValuesForKeysWithDictionary:dict]; 37 MessageFrame *messageFrame = [[MessageFrame alloc] init]; 38 messageFrame.message = message; 39 40 [self.messages addObject:messageFrame]; 41 } 42
1 // 滚动到最新的消息 2 NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0]; 3 [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。