国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[iOS基礎控件-6.9]聊天界面Demo

2019-11-14 19:47:17
字體:
來源:轉載
供稿:網友
A.需求
做出一個類似于QQ、微信的聊天界面
1.每個cell包含發送時間、發送人(頭像)、發送信息
2.使用對方頭像放在左邊,我方頭像在右邊
3.對方信息使用白色背景對話框,我方信息使用藍色背景對話框
4.隱藏相同的發送時間
5.底部功能按鈕:語音按鈕、消息輸入框、表情按鈕、附加按鈕
6.響應鍵盤事件,呼出鍵盤、隱藏鍵盤時對上述的視圖作出上移操作
7.鍵盤的發送事件處理
 
Code Source: https://github.com/hellovoidworld/ChatDemo
 
 
Image(108)
 
B.實現點
1.底層視圖搭建
上部分聊天信息框:UITableView
下部分功能區:UIButton
信息輸入框使用無邊框,然后使用自帶背景圖片,以保證在不同版本的iOS中樣式一致
9CEC2AC9-325F-44AA-8CBC-068833C5BD63
 
 
2.構建框架
依照“微博展示”的代碼框架,設計:
  • 自定義message模型
  • 自定義cell
  • 裝載了message模型和cell子控件位置尺寸的frame
 
Image(109)
 
3.使用擴展,給NSString加上文本size計算的功能
 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);
 
4.使用數據中的信息類型,判斷是我方發出的信息還是對方發出的信息,計算頭像和信息的位置
 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);
 
Image(110)
 
5.加上信息背景框
我方:使用藍色背景聊天框
對方:使用白色背景聊天框
重點:圖片的中心拉伸,利用圖片分別水平、垂直方向某個區域進行拉伸,保持其他部分的圖形 —>對UIImage使用擴展,返回具備了特定拉伸方式屬性的圖片
 
拉伸圖片方式屬性:
 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];
 
Image(111)
 
6.調整信息文字內邊距,讓文字被“包裹”在聊天框內
1     // 3.2 調整文字的內邊距2     textView.contentEdgeInsets = UIEdgeInsetsMake(TEXT_INSET, TEXT_INSET, TEXT_INSET, TEXT_INSET);
 
因為背景圖片邊緣有空白,改變了文字內邊距之后,高度會變高,需要對裝載信息的view的frame尺寸做出相應改變:
 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);
 
Image(112)
 
7.屏蔽相同的發送時間
(1)在message模型中定義一個標志
1 /** 是否隱藏發送時間 */2 @property(nonatomic, assign) BOOL hideTime;
 
(2)當控制器從plist文件裝載信息的時候初始化此標志
1 // 判斷是否發送時間與上一條信息的發送時間相同,若是則不用顯示了2 MessageFrame *lastMessageFrame = [mdictArray lastObject];3 if (lastMessageFrame && [message.time isEqualToString:lastMessageFrame.message.time]) {4      message.hideTime = YES;5 }
              
(3)只有hideTime ==  NO,計算frame的時候,長期需要計算發送時間的frame
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     }
 
Image(113)
 
8.響應鍵盤呼出縮回事件,上移或下移恢復整個版面(聊天區和功能區)
(1)設置控制器為鍵盤監聽器
    // 設置虛擬鍵盤監聽器
1     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
 
(2)編寫監聽方法
 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.取得彈出后的鍵盤frame11     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 }
 
Image(114)
 
9.設置數據框TextField,改變鍵盤
(1)當沒有文字的時候禁用回車,設置回車樣式
Image(115)
 
Image(116)
 
(2)調不出中文鍵盤
雖然在設置里面添加了中文鍵盤,但是依然找不到進入中文鍵盤的按鈕
 
 
10.發送消息
(1)拖入信息輸入框到控制器,設置控制器為輸入框TextField的代理
1     // 設置信息輸入框的代理2     self.inputView.delegate = self;
 
 
(2)響應回車事件
 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  

 

(3)自動滾動在最底端
1     // 滾動到最新的消息2     NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];3     [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
 
 
Image(117)
 
 
 
 
 
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 喀喇沁旗| 永顺县| 平顶山市| 调兵山市| 邯郸市| 平和县| 万州区| 南陵县| 东阳市| 丽江市| 绥德县| 报价| 九龙城区| 满洲里市| 拉萨市| 邛崃市| 东台市| 宜城市| 康乐县| 乐清市| 仙居县| 探索| 伊川县| 巴东县| 荆州市| 辽中县| 高清| 阳东县| 保靖县| 板桥市| 行唐县| 鄂州市| 郓城县| 濮阳市| 景德镇市| 西和县| 栾川县| 临猗县| 布尔津县| 北京市| 高平市|