UITableView的功能非常之强大,在IOS程序开发中处于非常重要的地位。本文针对QQ聊天界面的构建及自动回复功能的实现进行介绍
因本人初学,代码有很多不足之处,还请各种批评指正!
效果演示:



功能说明:
1.通过plist文件加载本地的聊天数据
2.如果两条信息的时间相同则隐藏第二个的时间
3.键盘起落的监听
4.半智能自动回复
5.(很容易但未添加)滑动屏幕,隐藏键盘
代码思路
0.先创建两个类,一个用来保存显示的数据,一个用来保存数据的框架。
1.我们需要拿到plist中的聊天记录,将数据转换成模型,加载进内存。
2.在框架数据中添加BOOL类型属性,保存是否显示时间的数据。取出上一条数据的时间与当前数据的时间比较,如果相同则尺寸为0。
3.显示这些数据,我们需要在屏幕中添加UITableVIew,每一个cell用来显示数据,每个cell的高度都不相同,在框架数据类中添加保存cell高度的属性。
4.添加UITableView的数据源为控制器,实现数据源方法。
5.数据显示成功之后,再考虑键盘的处理,需要用到消息中心机制监听键盘的显示和隐藏,并执行相应的动作。
6.实现sent键的功能,这里需要拿到文本框的文本,然后进行上面的数据处理,可以创建一个类对这些操作进行封装。
7.消息可以发送之后,再考虑消息自动回复功能。
8.自动回复就是创建一个plist文件保存自动回复的内容,如果输入的信息中有对应的回复消息则返回对应回复信息,如果没有则返回默认回复内容。
9.plist文件中分别取输入的每个字和key中的每个字进行对比,判断返回内容。
代码实现:
1 // 2 // KWViewController.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "KWViewController.h" 10 #import "KWMessageModel.h" 11 #import "KWMessageDeal.h" 12 #import "KWFrameModel.h" 13 #import "KWCellView.h" 14 15 @interface KWViewController () <UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate> 16 @property (weak, nonatomic) IBOutlet UITableView *tableView; 17 @property (weak, nonatomic) IBOutlet UITextField *input; 18 @property (nonatomic,strong) NSMutableArray * messages; 19 @end 20 21 @implementation KWViewController 22 //懒加载 23 - (NSMutableArray *)messages{ 24 if (!_messages) { 25 NSString * path = [[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]; 26 NSArray *array = [NSArray arrayWithContentsOfFile:path]; 27 NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:array.count]; 28 for (NSDictionary *dict in array) { 29 KWFrameModel * last = [arrayM lastObject]; 30 KWMessageModel *model = [KWMessageModel messageWithDict:dict]; 31 KWFrameModel *frame = [[KWFrameModel alloc] init]; 32 if ([last.model.time isEqualToString:model.time]) { 33 frame.timeshow = NO; 34 }else{ 35 frame.timeshow = YES; 36 } 37 frame.model = model; 38 [arrayM addObject:frame]; 39 } 40 _messages = [arrayM mutableCopy]; 41 } 42 return _messages; 43 } 44 - (void)viewDidLoad{ 45 [super viewDidLoad]; 46 self.tableView.dataSource = self; 47 self.tableView.delegate = self; 48 self.input.delegate = self; 49 NSNotificationCenter * center = [NSNotificationCenter defaultCenter]; 50 [center addObserver:self selector:@selector(keyboardDidChange:) name:UIKeyboardWillChangeFrameNotification object:nil]; 51 } 52 # pragma mark 键盘处理 53 - (void)keyboardDidChange:(NSNotification *)notification{ 54 // userInfo = { 55 // UIKeyboardAnimationCurveUserInfoKey = 7; 56 // UIKeyboardAnimationDurationUserInfoKey = "0.25"; 57 // UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 216}}"; 58 // UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 588}"; 59 // UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 372}"; 60 // UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 480}, {320, 216}}"; 61 // UIKeyboardFrameChangedByUserInteraction = 0; 62 // UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 264}, {320, 216}}"; 63 CGFloat keyboardY = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y; 64 CGFloat viewH = self.view.frame.size.height; 65 CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; 66 [UIView animateKeyframesWithDuration:duration delay:0 options:7<<16 animations:^{ 67 self.view.transform = CGAffineTransformMakeTranslation(0, keyboardY - viewH); 68 } completion:^(BOOL finished) { 69 70 }]; 71 } 72 #pragma mark 数据源方法 73 74 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 75 return self.messages.count; 76 } 77 78 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 79 KWCellView *cell = [KWCellView cellViewWithTableView:tableView]; 80 KWFrameModel *currentFrame = self.messages[indexPath.row]; 81 cell.frameM = currentFrame; 82 return cell; 83 } 84 85 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 86 KWFrameModel * framem = self.messages[indexPath.row]; 87 return framem.cellH; 88 } 89 # pragma mark 发送信息 90 - (void)sentMessage{ 91 NSString *str = self.input.text; 92 KWMessageModel * sent = [KWMessageDeal messageDealWithContext:str type:0]; 93 KWFrameModel *Fsent = [[KWFrameModel alloc] init]; 94 //是否显示时间 95 KWFrameModel *last = self.messages.lastObject; 96 97 if ([last.model.time isEqualToString:sent.time]) { 98 Fsent.timeshow = NO; 99 }else{ 100 Fsent.timeshow = YES; 101 } 102 Fsent.model = sent; 103 [self.messages addObject:Fsent]; 104 } 105 # pragma mark textfield代理 106 - (BOOL)textFieldShouldReturn:(UITextField *)textField{ 107 [self.view endEditing:YES]; 108 [self sentMessage]; 109 KWMessageModel *answer = [KWMessageDeal autoAnswer:self.input.text]; 110 KWFrameModel *Fanswer = [[KWFrameModel alloc] init]; 111 Fanswer.model = answer; 112 [self.messages addObject:Fanswer]; 113 self.input.text = nil; 114 [self.tableView reloadData]; 115 NSIndexPath * path = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0]; 116 [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 117 return YES; 118 } 119 120 @end
1 // 2 // KWMessageModel.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "KWMessageModel.h" 10 11 @interface KWMessageModel () 12 { 13 UIImage *_mimg; 14 UIImage *_micon; 15 } 16 @end 17 @implementation KWMessageModel 18 //生成图片 19 - (UIImage *)mimg{ 20 if (_mimg) { 21 _mimg = [UIImage imageNamed:self.img]; 22 } 23 return _mimg; 24 } 25 26 27 //工厂方法 28 - (instancetype)initWithDict:(NSDictionary *)dict{ 29 if (self = [super init]) { 30 [self setValuesForKeysWithDictionary:dict]; 31 } 32 return self; 33 } 34 + (instancetype)messageWithDict:(NSDictionary *)dict{ 35 return [[self alloc] initWithDict:dict]; 36 } 37 @end
1 // 2 // KWFrameModel.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "KWFrameModel.h" 10 11 @implementation KWFrameModel 12 - (void)setModel:(KWMessageModel *)model{ 13 _model = model; 14 //屏幕尺寸 15 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 16 //计算时间框架 17 CGFloat timeX = 0; 18 CGFloat timeY = 0; 19 CGFloat timeW = screenWidth; 20 CGFloat timeH = kTimeH; 21 //计算时间是否隐藏 22 if (self.isTimeShow) { 23 self.timeF = CGRectMake(timeX, timeY, timeW, timeH);CGRectMake(0, 0, 0, 0); 24 }else{ 25 self.timeF = CGRectMake(0, 0, 0, 0); 26 } 27 //计算图标框架 28 CGFloat iconW = kIconW; 29 CGFloat iconH = kIconH; 30 CGFloat iconX; 31 //判断消息类型 32 if (KWMessageTypeMe == self.model.type) { 33 iconX = screenWidth - kMargin - kIconW; 34 }else{ 35 iconX = kMargin; 36 } 37 CGFloat iconY = CGRectGetMaxY(self.timeF) + kMargin; 38 self.iconF = CGRectMake(iconX, iconY, iconW, iconH); 39 //计算信息框架 40 CGSize textS = [self.model.text rectWithWidth:200 Heigth:MAXFLOAT FontSize:14]; 41 CGFloat textW = textS.width + 2 * kTextEdgeInSets; 42 CGFloat textH = textS.height + 2 * kTextEdgeInSets; 43 CGFloat textX; 44 if (KWMessageTypeMe == self.model.type) { 45 textX = screenWidth - kMargin - iconW - textW; 46 }else{ 47 textX = kMargin + iconW; 48 } 49 CGFloat textY = iconY; 50 self.textF = CGRectMake(textX, textY, textW, textH); 51 //行高 52 self.cellH = MAX(CGRectGetMaxY(self.iconF), CGRectGetMaxY(self.textF)) + kMargin; 53 } 54 /** 55 * 重新描述 56 */ 57 - (NSString *)description{ 58 NSString *str = [NSString stringWithFormat:@"time%@-icon%@-text%@",NSStringFromCGRect(self.timeF),NSStringFromCGRect(self.iconF),NSStringFromCGRect(self.textF)]; 59 return str; 60 } 61 @end
1 // 2 // KWMessageDeal.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "KWMessageDeal.h" 10 11 @interface KWMessageDeal () 12 { 13 NSString *_time; 14 } 15 16 @end 17 18 @implementation KWMessageDeal 19 + (KWMessageModel *)messageDealWithContext:(NSString *)context type:(KWMessageType)type{ 20 KWMessageDeal *deal = [[KWMessageDeal alloc] init]; 21 KWMessageModel *model = [[KWMessageModel alloc] init]; 22 model.text = context; 23 model.type = type; 24 model.time = deal.time; 25 return model; 26 } 27 - (NSString *)time{ 28 NSDate *date = [[NSDate alloc] init]; 29 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 30 formatter.dateFormat = @"HH:mm"; 31 NSString *time = [formatter stringFromDate:date]; 32 return time; 33 } 34 - (NSDictionary *)answers{ 35 if (!_answers) { 36 NSString *path = [[NSBundle mainBundle] pathForResource:@"answer.plist" ofType:nil]; 37 _answers = [NSDictionary dictionaryWithContentsOfFile:path]; 38 } 39 return _answers; 40 } 41 + (KWMessageModel *)autoAnswer:(NSString *)receive{ 42 KWMessageDeal *deal = [[KWMessageDeal alloc] init]; 43 NSString *answer = nil; 44 for (int i =0; i<receive.length; i++) { 45 NSString *str1 = [NSString stringWithFormat:@"%C",[receive characterAtIndex:i]]; 46 NSArray *keys = [deal.answers allKeys]; 47 for (int j = 0; j<keys.count; j++) { 48 NSString *key = keys[j]; 49 for (int k = 0; k< key.length; k++) { 50 NSString *str2 = [NSString stringWithFormat:@"%C",[key characterAtIndex:k]]; 51 if ([str1 isEqualToString:str2]) { 52 answer = deal.answers[key]; 53 return [self messageDealWithContext:answer type:1]; 54 } 55 } 56 } 57 } 58 answer = @"我看不懂啊!"; 59 return [self messageDealWithContext:answer type:1]; 60 } 61 @end
1 // 2 // NSString+my.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "NSString+my.h" 10 11 @implementation NSString (my) 12 - (CGSize)rectWithWidth:(CGFloat)width Heigth:(CGFloat)height FontSize:(int)fontSize { 13 NSDictionary *dict = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}; 14 CGRect rect = [self boundingRectWithSize:CGSizeMake(width, height) options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil]; 15 return rect.size; 16 } 17 @end
1 // 2 // UIImage+my.m 3 // 19-扣扣聊天(优化) 4 // 5 // Created by kevin on 14-6-1. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "UIImage+my.h" 10 11 @implementation UIImage (my) 12 + (UIImage *)imageResize:(UIEdgeInsets)edgeInsets Named:(NSString *)name{ 13 UIImage *img = [UIImage imageNamed:name]; 14 return [img resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch]; 15 } 16 @end
对应的.h文件没有什么内容,仅是一些声明暂不提供!
浙公网安备 33010602011771号