在现阶段的通信服务中,各种标准都有,因此会出现无法实现相互连通,而XMPP(Extensible Message and presence Protocol)协议的出现,实现了整个及时通信服务协议的互通。有了这个协议之后,使用任何一个组织或者个人提供的即使通信服务,都能够无障碍的与其他的及时通信服务的用户进行交流。例如google 公司2005年推出的Google talk就是一款基于XMPP协议的即时通信软件。在前面的系列博文中,我们介绍了XMPP的详细使用(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#xmpp),下面我们就谈论一下如何简单的使用XMPP的键盘订制:

  1、首先增加键盘的自定义小图标和弹出效果

  效果图如下:

#pragma mark  - 排列按钮
- (void) setUpSubviews{ //1 初始化图片名称
NSArray* array=@[@"compose_camerabutton_background_os7",@"compose_toolbar_picture_os7",@"compose_mentionbutton_background_os7",@"compose_trendbutton_background_os7",@"compose_emoticonbutton_background_os7"]; //2 排列按钮
CGFloat space=(kWidth-kMargin*-kItemNum*kItemWidth)/(kItemNum-)+kItemWidth; for (int i=; i<kItemNum; i++) { UIButton * button=[UIButton buttonWithType:UIButtonTypeCustom];
button.tag=i;
button.frame=CGRectMake(kMargin+i*space, self.frame.size.height/2.0-kItemHeight/2.0, kItemWidth, kItemHeight); // button.backgroundColor=JRRandomColor();
[button setBackgroundImage:[UIImage imageNamed:array[i]] forState:UIControlStateNormal]; //Actions 按钮事件
[button addTarget:self action:@selector(btClick:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:button];
} } /增加键盘事件弹出通知监控
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyUp:) name:UIKeyboardWillShowNotification object:nil]; //增加键盘事件消失通知监控
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyDown:) name:UIKeyboardWillHideNotification object:nil]; #pragma mark - 键盘升起来
- (void) keyUp:(NSNotification *) notification{ //获取动画的时间
CGFloat animaTime=[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; //获取键盘的尺寸(用来确定动画的范围)
CGRect frame=[notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; //控制键盘动画
[UIView animateWithDuration:animaTime animations:^{
self.keyAccess.transform=CGAffineTransformMakeTranslation(, frame.size.height*-);
}]; }
#pragma mark - 键盘落下去
- (void) keyDown:(NSNotification *) notification{ //获取动画的时间
CGFloat animaTime=[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; [UIView animateWithDuration:animaTime animations:^{
self.keyAccess.transform=CGAffineTransformIdentity;
}]; }

  2、定义自定义键盘的图标

  表情主要分为三块默认,Emoji,浪小花,默认和浪小花为图标,而Emoji为字符,因此我们需要进行特殊处理。效果图如下:

  代码如下:

  1、我们首先自定义键盘视图,同时我们需要把表情抽取出来因此还需要自定义一个滚动表情视图

  //增加滚动表情
[self setUpSrollEmotion]; //增加自定义的tab
[self setUpTab]; //设置默认第一个
if (self.btArray.count>) {
[self clickBt:self.btArray[]];
self.emotionScroll.emotionArray=self.defaultArray;
}else{
[self clickBt:[self.btArray firstObject]];
}
pragma mark - 自定义键盘布局
#pragma mark 设置滚动表情
- (void) setUpSrollEmotion{ JRScrollEmotion * scroll=[[JRScrollEmotion alloc] initWithFrame:CGRectMake(, , kWidth, self.frame.size.height-)];
self.emotionScroll=scroll; scroll.emotionArray=nil;
[self addSubview:scroll]; } #pragma mark 增加tab
- (void) setUpTab{ UIView * bgview=[[UIView alloc] initWithFrame:CGRectMake(, self.frame.size.height-, kWidth, )];
bgview.backgroundColor=JRColor(, , );
[self addSubview:bgview]; //计算按钮宽度
CGFloat width=kWidth/4.0;
//标题数组
NSArray * array=@[@"最近",@"默认",@"Emoji",@"浪小花"]; for (int i= ; i<; i++) { UIButton * button=[[UIButton alloc] initWithFrame:CGRectMake(i*width, , width, )];
button.tag=i;
[button setTitle:array[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(clickBt:) forControlEvents:UIControlEventTouchUpInside];
[self.btArray addObject:button];
[bgview addSubview:button]; } }

  2、第二步我们需要进行对表情进行循环布局,每个表情作为一个button,我们进行循环摆放

-(void)setEmotionArray:(NSArray *)emotionArray{
_emotionArray=emotionArray; //移除所有button
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; //计算总页数
NSInteger totalPage=ceil(self.emotionArray.count/23.0);
self.contentSize=CGSizeMake(totalPage*kWidth, );
CGFloat hspace=(kWidth--*)/7.0+;
CGFloat vspace=(self.frame.size.height--*)/2.0+; for (int i=; i<self.emotionArray.count; i++) {
NSInteger nowPage=[self getNowPageWith:i]; NSInteger col=(i-nowPage*)%;
NSInteger row=(i-nowPage*)/; UIButton *button=[[UIButton alloc ] initWithFrame:CGRectMake(nowPage*kWidth++col*hspace, +row*vspace, , )]; //根据表类型设置图片
JREmotionModel * model=self.emotionArray[i]; if (model.imageName==nil) {//emoji表情
[button setTitle:model.emoji forState:UIControlStateNormal];
button.titleLabel.font=[UIFont systemFontOfSize:];
}else{
[button setImage:[UIImage imageNamed:model.imageName] forState:UIControlStateNormal];
} //监控点击事件
button.tag=i;
[button addTarget:self action:@selector(emotionClick:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button]; } for (int i=; i<totalPage; i++) { //增加删除按钮
UIButton *button= [UIButton buttonWithType:UIButtonTypeCustom]; if (i<totalPage-) {
button.frame=CGRectMake(kWidth--+i*kWidth, vspace*+, , );
}else{
//获取剩下的个数
NSInteger numLeft= self.emotionArray.count-i*;
NSInteger row=(numLeft)/;
NSInteger col=(numLeft)%;
button.frame=CGRectMake(i*kWidth++hspace*col, +vspace*row, , );
} //====
[button setImage:[UIImage imageNamed:@"compose_emotion_delete_highlighted"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(emotionDelete) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:button]; } }

  3、我们需要进行图文混排将信息展示到文本框

    ①当点击表情的时候我们需要发送通知,告诉接受者

#pragma mark - 表情点解
- (void) emotionClick:(UIButton *) button{ //获取对应的表情模型
JREmotionModel *model=self.emotionArray[button.tag]; //发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:AddEmotionNotification object:nil userInfo:@{@"emotion":model}];

    ②接收到通知后通过富文本技术进行显示

- (void)addEmotion:(NSNotification * ) notification{

   JREmotionModel * model= notification.userInfo[@"emotion"];

    //如果是Emoji表情直接插入文本即可
if (model.imageName.length==) {
[self.tf insertText:model.emoji];
}else{
//获取之前的文本
NSAttributedString * text=self.tf.attributedText; //将之前的文本包含进去
NSMutableAttributedString * attr=[[NSMutableAttributedString alloc] initWithAttributedString:text]; //记录当前的位置
NSInteger index; //如果是图片表情,需要重新初始化一个附件,并设置图片然后拼接
JRTextAttachMent * temAttch=[[JRTextAttachMent alloc] init];
temAttch.model=model;
temAttch.bounds=CGRectMake(, -2.5, self.tf.font.lineHeight-, self.tf.font.lineHeight-);
temAttch.image=[UIImage imageNamed:model.imageName]; NSAttributedString * tempStr=[NSAttributedString attributedStringWithAttachment:temAttch]; //保存一下之前的位置
index=self.tf.selectedRange.location;
[attr insertAttributedString:tempStr atIndex:index]; //重新给文本框赋值
[attr addAttribute:NSFontAttributeName value:self.tf.font range:NSMakeRange(, attr.length)];
self.tf.attributedText=attr;
self.tf.selectedRange=NSMakeRange(index+, ); } }

  想要了解更多内容的小伙伴,可以点击查看源码,亲自运行测试。

  疑问咨询或技术交流,请加入官方QQ群: (452379712)

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

XMPP键盘订制实现图文混排的更多相关文章

  1. Swift3.0 功能二 (表情键盘与图文混排)

    随着iOS越来越多表情键盘以及图文混排的需求,本文运用Swift3.0系统的实现其功能以及封装调用方法,写的不好,如有错误望各位提出宝贵意见,多谢 项目源码地址: 相关知识点都有标识 项目源码地址 废 ...

  2. 仿QQ聊天图文混排流程图【适用于XMPP】

      图文混排流程图.graffle4.8 KB   下面附上图片素材: 表情.zip692.5 KB     下面是字符串与图片的详细对应关系:                 "[呲牙]& ...

  3. 用NSAttributedString实现简单的图文混排

    iOS7以后,因为TextKit的强大,可以用NSAttributedString很方便的实现图文混排(主要是利用了NSTextAttachment). 关于Textkit的牛逼之处,可以参考objc ...

  4. AS3聊天单行输入框图文混排完美实现

    几年前刚毕业.第一个游戏模块做的就是聊天.到如今.几个游戏写过几次聊天模块. 之前在4399做的<幻龙骑士>(又名<神骑士>),还有上周六刚上线的<疯狂的子弹>, ...

  5. iOS 图文混排 链接 可点击

    对于这个话题 我想到 1 第一个解决方法就是使用 webView 比较经典 把所有复杂工作都交给控件本身去处理了,  但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实 ...

  6. 图文混排--CoreText的简单运用

    常见的在一些微博微信中可以看见一段文字中有不同的字体,字体有不同的颜色,并且可能会有一些笑脸之类的表情,这些可以通过图文混排做到. 图文混排可以通过WebView和CoreText做到,其他还有别的方 ...

  7. 【转】关于FLASH中图文混排聊天框的小结

    原文链接 图文混排也是FLASH里一个很古老的话题了,我们不像美国佬那样游戏里面聊天框就是聊天框,全是文字干干净净,也不像日本人发明了并且频繁地使用颜文字.不管是做论坛.做游戏,必定要实现的一点就是带 ...

  8. DIV+CSS 图文混排的图片居中办法

    不少人为了让 Div 图文混排的图片可以居中,给 IMG 套各式各样的 SPAN.DIV.LI 等等,以便于使用 text-align来进行居中. <div>图文混排 <br> ...

  9. ios图文混排

    图文混排的形式 1. 富文本形式 2. core Text(文字排版) 3. TextKit 4. UIWebView 一.富文本 我们可以采用attributeString来进行图文混排.例如一个文 ...

随机推荐

  1. PHP获取以为数组中的最大值和最小值

    1.PHP获取一维数组中的最大值 <?php $a=array('1','3','55','99'); $pos = array_search(max($a), $a); echo $a[$po ...

  2. codeforces-727A

    题目连接:http://codeforces.com/contest/727/problem/A A. Transformation: from A to B time limit per test ...

  3. 【Python】闭包Closure

    原来这就是闭包啊... 还是上次面试,被问只不知掉js里面的闭包 闭包,没听过啊...什么是闭包 回来查了下,原来这货叫闭包啊...... —————————————————————————————— ...

  4. java8新特性——Stream API

    Java8中有两大最为重要得改变,其一时Lambda表达式,另外就是 Stream API了.在前面几篇中简单学习了Lambda表达式得语法,以及函数式接口.本文就来简单学习一下Stream API( ...

  5. 【BZOJ 3442】 3442: 学习小组 (最大费用流)

    3442: 学习小组 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 403  Solved: 193 Description [背景] 坑校准备鼓励学生 ...

  6. 「APIO2018选圆圈」

    「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...

  7. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  8. AOP 面向切面 记录请求接口的日志

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点, ...

  9. bzoj 1911: [Apio2010]特别行动队 -- 斜率优化

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Description Input Output Sample Input 4 ...

  10. js判断移动设备

    在开发中可能需要去判断用户的设备重定向到相应的网址: 1. 判断 iPhone  Android  iPod if((navigator.userAgent.match(/iPhone/i))||(n ...