热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IOSQQ聊天界面的构建及自动回复功能的实现白衣→黑马

IOSQQ聊天界面的构建及自动回复功能的实现UITableView的功能非常之强大,在IOS程序开发中处于非常重要的地位。本文针对QQ聊天界面的构建及自动回复功能的实现进行介绍因本

IOS QQ聊天界面的构建及自动回复功能的实现


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 ()
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

KWViewController.m

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

KWMessageModel.m

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

KWFrameModel.m

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) {
45 NSString *str1 = [NSString stringWithFormat:@"%C",[receive characterAtIndex:i]];
46 NSArray *keys = [deal.answers allKeys];
47 for (int j = 0; j) {
48 NSString *key = keys[j];
49 for (int k = 0; 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

KWMessageDeal.m

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

NSString+my.m

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

UIImage+my.m

对应的.h文件没有什么内容,仅是一些声明暂不提供!

 

发表于

2014-06-03 00:42 

白衣→黑马 

阅读(722

评论(0

编辑 

收藏 

举报

 



推荐阅读
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 学习Java异常处理之throws之抛出并捕获异常(9)
    任务描述本关任务:在main方法之外创建任意一个方法接收给定的两个字符串,把第二个字符串的长度减1生成一个整数值,输出第一个字符串长度是 ... [详细]
author-avatar
mobiledu2502927267
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有