文档章节

iOS自定义的emoji表情键盘

珲少
 珲少
发布于 2015/11/11 19:05
字数 1108
阅读 7633
收藏 9

iOS自定义的表情键盘

一、关于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://pan.baidu.com/s/1o6AdkBw

专注技术,热爱生活,交流技术,也做朋友。

——珲少 QQ群:203317592

© 著作权归作者所有

珲少

珲少

粉丝 875
博文 390
码字总数 469911
作品 0
上海
iOS工程师
私信 提问
加载中

评论(3)

潘利改
潘利改
不是完成,是“发送”这两个字13
潘利改
潘利改
imageViewTap这个方法是在点击笑脸出现的吗?再点击笑脸切换成系统键盘的时候,又重新刷新了一下inputView,完成这两个字发生了重叠,这个怎么解决呢?
南溟之巅
大神,能提供源码吗?我按照你博客做出来的键盘,CollectionView会出现重影
mysql utf8mb4与emoji表情

MYSQL 5.5 之前, UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区, BMP是从哪到哪,到http://en.wikipedia.org/wiki/MappingofUnicodecharacters这里看,基本就是0000~FFFF这一...

铂金大雕
2013/08/17
0
5
Unicode 组织宣布明年 Emoji 增加有色人种表情

Unicode 组织(Unicode Consortium)发布了技术报告,详细说明了增加多民族表现形式的 Emoji 新处理方法。之前的规定指出,Emoji 表情表现种族、民族和性别时需要尽可能的保持中性,除非需要...

oschina
2014/11/05
2.4K
13
苹果向开发者发布第四个 iOS 8.3 测试版

苹果今天向开发者发布了第四个 iOS 8.3 测试版,距离 iOS 8.3 第三个测试版发布相隔两周时间。距离 iOS 8.3 第一个测试版发布相隔一个半月时间。iOS 8.3 beta 4 的编译号为 12F5061,开发者可...

oschina
2015/03/25
668
0
iOS 8.3 测试版发布:Apple Pay 很快进入中国!

苹果今天发布了 iOS 8.3 第一册测试版,而一周前发布的 iOS 8.2 第五个测试版也正在测试之中。iOS 8.3 的编译号为12F5027d,这次发布的还包括 Xcode 6.3 测试版以及 Swift 1.2。 iOS 8.3 新功...

oschina
2015/02/10
1K
6
Unicode 11候选版发布,新增“OK”笑脸等67个Emoji表情

由于 Unicode 11 尚未正式发布,届时这些表情设计可能还会有变动。 就在今年6月底,统一码技术委员会(Unicode Consortium)正式公布了Unicode 10当中可供用户使用的56个新Emoji表情。据Emo...

局长
2017/08/05
897
8

没有更多内容

加载失败,请刷新页面

加载更多

为什么加个注解@Transtaional就可以保证事务的一致性和完整性?

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http:......

architect刘源源
34分钟前
2
0
硅谷对于禁华为坐立不安

5 月 15 日,美国商务部决定把华为及其多家关联公司列入一份“实体名单”后,20 日又宣布给与华为 90 天“临时执照”,为“依赖华为设备的美国通信商留出余地”。 尽管目前给出了“临时执照”...

linuxCool
今天
3
0
Java—System类入门学习

第三阶段 JAVA常见对象的学习 System类 System类包含一些有用的字段和方法,他不能被实例化 //用于垃圾回收public static void gc()//终止正在运行的java虚拟机。参数用作状态码,根据惯例...

BWH_Steven
今天
6
0
OSChina 周日乱弹 —— 喝了维他茶,忘了那个她

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoniezi :#今日歌曲推荐#哈哈哈洗脑《土拨鼠之歌》 《土拨鼠之歌》 手机党少年们想听歌,请使劲儿戳(这里) 周六…… 不是该休息么, 被...

小小编辑
今天
639
11
你需要知道的 5 个 Linux 新手会犯的失误

Linux 爱好者们分享了他们犯下的一些最大错误。 终身学习是明智的 —— 它可以让你的思维敏捷,让你在就业市场上更具竞争力。但是有些技能比其他技能更难学,尤其是那些小菜鸟错误,当你尝试...

xiangyunyan
今天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部