一、关于emoji表情

随着iOS系统版本的升级,对原生emoji表情的支持也越来越丰富。emoji表情是unicode码中为表情符号设计的一组编码,当然,还有独立于unicode的另一套编码SBUnicode,在OS系统中,这两种编码都有很好的支持。UI系统会自动帮我们将编码转义成表情符号,例如用SBUnicode如下代码:

UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    label.font = [UIFont systemFontOfSize:25];
    label.text = @"\uE056";
    [self.view addSubview:label];

就会在屏幕上出现一个笑脸:

二、开发表情键盘的思路

首先为了实现跨平台,无论iOS端,andorid端还是web端,都要有一个相同的标准,这个标准就可以是国际Unicode编码,我们的思路是将表情文字进行unicode编码后再进行传输,因此,有两中方式,一种是通过自定义一套表情切图,将其与unicode码一一对应,在转码的时候,我们一一遍历,转换成unicode后进行传输,这样的好处是我们可以保证所有平台所能使用的表情统一。在iOS端,可以有另一种方式,通过上面我们知道,通过SBUnicode码我们可以在客户端显示表情符号,并且这个码的排列是十分有规律的,通过这个特点,我们可以通过遍历SBUnicode码的范围进行表情的创建,省去的图片素材的麻烦。

iOS中可用的表情unicode范围是:0xE001~0xE05A,0xE101~0xE15A,

0xE201~0xE253,0xE401~0xE44C,0xE501~0xE537。

我们可以通过遍历的方法,将其都加入数据源数组中:

int emojiRangeArray[10] = {0xE001,0xE05A,0xE101,0xE15A,0xE201,0xE253,0xE401,0xE44C,0xE501,0xE537};
    for (int j = 0 ; j<10 ; j+=2 ) {
         
        int startIndex = emojiRangeArray[j];
        int endIndex = emojiRangeArray[j+1];
         
        for (int i = startIndex ; i<= endIndex ; i++ ) {
        //添加到数据源数组
            [dataArray addObject:[NSString stringWithFormat:@"%C", (unichar)i]];
        }
    }

键盘的摆放,可以通过collectionView来做,十分方便:

//为了摆放分页控制器,创建一个背景view
    bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 200)];
    //分页控制器
    pageControlBottom = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 170, [UIScreen mainScreen].bounds.size.width, 20)];
    [bgView addSubview:pageControlBottom];
    //collectionView布局
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc]init];
    //水平布局
    layout.scrollDirection=UICollectionViewScrollDirectionHorizontal;
    //设置每个表情按钮的大小为30*30
    layout.itemSize=CGSizeMake(30, 30);
    //计算每个分区的左右边距
    float xOffset = (kscreenWidth-7*30-10*6)/2;
    //设置分区的内容偏移
    layout.sectionInset=UIEdgeInsetsMake(10, xOffset, 10, xOffset);
    scrollView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 160) collectionViewLayout:layout];
    //打开分页效果
    scrollView.pagingEnabled = YES;
    //设置行列间距
    layout.minimumLineSpacing=10;
    layout.minimumInteritemSpacing=5;
     
    scrollView.delegate=self;
    scrollView.dataSource=self;
    scrollView.backgroundColor = bgView.backgroundColor;
    [bgView addSubview:scrollView];

在collectionView的回调方法中,处理如下:

//每页28个表情
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    if (((dataArray.count/28)+(dataArray.count%28==0?0:1))!=section+1) {
        return 28;
    }else{
        return dataArray.count-28*((dataArray.count/28)+(dataArray.count%28==0?0:1)-1);
    }
    
}
//返回页数
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return (dataArray.count/28)+(dataArray.count%28==0?0:1);
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"biaoqing" forIndexPath:indexPath];
    for (int i=cell.contentView.subviews.count; i>0; i--) {
        [cell.contentView.subviews[i-1] removeFromSuperview];
    }
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 30, 30)];
    label.font = [UIFont systemFontOfSize:25];
    label.text =dataArray[indexPath.row+indexPath.section*28] ;
    
     
    [cell.contentView addSubview:label];
    return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    NSString * str = dataArray[indexPath.section*28+indexPath.row];
    //这里手动将表情符号添加到textField上
     
}
//翻页后对分页控制器进行更新
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat contenOffset = scrollView.contentOffset.x;
    int page = contenOffset/scrollView.frame.size.width+((int)contenOffset%(int)scrollView.frame.size.width==0?0:1);
    pageControlBottom.currentPage = page;
 
}
 
三、切换系统键盘和自定义的表情键盘

UITextField和UITextView都会有下面这个属性和方法:

@property (nullable, readwrite, strong) UIView *inputView;   
- (void)reloadInputViews;

inputView我们可以设置textView和textField成为第一响应时的弹出附件,如果我们不设置或者设置为nil,则会弹出系统键盘,reloadInputView方法可以使我们刷新这个附件视图,通过这两个,我们可以非常轻松的实现键盘的切换,比如我们在一个出发方法中如下处理:

-(void)imageViewTap{
    if (![_publishContent isFirstResponder]) {
        return;
    }
    if (isEmoji==NO) {
        isEmoji=YES;
        //呼出表情
        _textView.inputView=bgView;
        [_textView reloadInputViews];
    }else{
        isEmoji=NO;
        _textView.inputView=nil;
        [_textView reloadInputViews];
    }
 
     
}

效果如下:

追注:测试上面的SBUnicode码在模拟器上可以正常显示,真机并不能识别,可以通过将表情符全部添加到一个plist文件中,通过文件读取来创建键盘的方式进行真机上的开发。plist文件地址如下

------------------------------------------分割线------------------------------------------

免费下载地址在 http://linux.linuxidc.com/

用户名与密码都是www.linuxidc.com

具体下载目录在 /2015年资料/12月/12日/iOS自定义的emoji表情键盘/

下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm

------------------------------------------分割线------------------------------------------

本文永久更新链接地址http://www.linuxidc.com/Linux/2015-12/126157.htm

自定制emoji替换系统的emoji键盘的更多相关文章

  1. 【Cocos2d-x】屏蔽Emoji并解决由于Emoji导致的崩溃问题

    IOS的Emoji表情因为编码问题,在Android手机上无法正常显示,如果当前的cc.Label节点使用的是系统字,在系统字库中找不到对应编码的字符,会导致崩溃. 为了解决这个问题,又要兼顾新老版本 ...

  2. Windows 7 封装篇(一)【母盘定制】[手动制作]定制合适的系统母盘

    Windows 7 封装篇(一)[母盘定制][手动制作]定制合适的系统母盘 http://www.win10u.com/article/html/10.html Windows 7 封装篇(一)[母盘 ...

  3. 介绍一种很棒的wince 如何替换系统声音的方法

    Topic:介绍一种很棒的wince 如何替换系统声音的方法(作者:Baiduluckyboy) //------------------------------------------------- ...

  4. 替换系统数据库解决SQLSERVER服务启动不了的问题

    替换系统数据库解决SQLSERVER服务启动不了的问题 当遇到SQLSERVER服务启动不起来的时候,我们试过把系统的四个数据库master ,model ,tempdb,msdb 替换掉,Windo ...

  5. 定制x86 Linux系统

    /************************************************************************************* * 定制x86 Linux ...

  6. android使用mount挂载/system/app为读写权限,删除或替换系统应用

    注意:以下代码中#开头的则为需要执行的shell命令,其他的为打印的结果.#代表需要使用ROOT权限(su)执行,所以想要修改您android手机某个目录挂载为读写,首先需要有ROOT权限! 先要得到 ...

  7. iOS之自定义UITabBar替换系统默认的(添加“+”号按钮)

    自定义UITabBar替换系统默认的,目的是为了在UITabBar中间位置添加一个“+号按钮”,下面我们来聊聊具体的实现. 1.自定义WBTabBar,让其继承自UITabBar,代码如下: // / ...

  8. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  9. iOS自定制tabbar与系统的tabbar冲突,造成第一次点击各个item图片更换选中,第二次选中部分item图片不改变

    可以选择是使用自定制的还是系统的,如果使用自定制的,就使用以下方法即可隐藏系统的uitabbarButton,从而使item恢复正确 //隐藏UITabBarButton -(void)viewWil ...

随机推荐

  1. php 通过referer防盗链(以图片为例)

    1.在网页里访问站外图片时,服务器如何知道是在站外引用的呢? (1)对比本服务器请求与跨服务器请求 图一——本服务器请求 图二——显示盗链的referer信息 通过对比也就知道referer显示的是引 ...

  2. selenium 学习笔记 ---新手学习记录(8) 问题总结(java)

    1.获取执行js代码后的返回值 //获取滚动距离 String jl="return $('#chapterul li').height();"; Long jlhq=(Long) ...

  3. Eclipse+ADT的环境搭建

    Index: . Java环境变量的设置 . Android环境变量的设置 1.Java环境变量的设置 A.属性名称:JAVA_HOME 属性值:C:\Program Files\Java\jdk1. ...

  4. C/C++ 基础教程

          自从做IOS后,就比较少用纯C++的方式写代码了,因为Obj-C的代码风格和C++的风格还是有一点区别的.怕自己忘记了C/C++的基础.整理了一些C/C++基础的网站,供大家学习C/C++ ...

  5. Balanced Binary Tree --Leetcode C++

    递归 左子树是否为平衡二叉树 右子树是否为平衡二叉树 左右子树高度差是否大于1,大于1,返回false 否则判断左右子树 最简单的理解方法就是如下的思路: class Solution { publi ...

  6. [置顶] SQL日期类型

    在做机房收费系统的时候,上下机,我觉得是我在整个系统中遇到最棘手的问题了,现在就给大家,分享一下,我是怎样解决的. SQL中有3中数据类型是关于日期的,每一种的用法是不同的,当你用错了,就会出现下面这 ...

  7. Intellij IDEA创建Maven Web项目

    1前言 在创建项目中,IDEA提供了非常多项目模板,比方Spring MVC模板,能够直接创建一个基于Maven的Spring MVC的demo,各种配置都已经设定好了,直接编译部署就能够使用. 最開 ...

  8. DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接)

    首先,我们贴出上一节Users类XPO对象的保存代码,直接建立的XPO Session会话,因为没有与我们所期望的数据层建立绑定, 所以程序自动创建了一个Access数据库,作为默认数据库操作对象来使 ...

  9. iOS离线打包

    预备环境 iOS开发环境,Mac OS.XCode 7.2以上版本: 下载HBuilder离线打包iOS版SDK(5+ SDK下载). SDK目录说明 HBuilder-Hello:离线打包演示应用: ...

  10. Onvif协议

    ONVIF致力于通过全球性的开放界面标准来推进网络视频在安防市场的应用,这一接口界面标准将确保不同厂商生产的网络视频监控产品具有互通性.2008年11月,论坛正式发布了ONVIF第一版规范ONVIF核 ...