1、切换键盘

1.1 结构分析

iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情

1.2 初步实现思路

1>按上述结构分好层级后,自定义HWEmotionKeyboard,继承UIView,代表表情键盘(整体),自定义HWEmotionTabBar,继承UIView,代表表情键盘底部的选项卡,自定义HWEmotionListView,代表表情键盘顶部的表情内容(显示所有表情,包括一个ScrollView和PageControl)
2>在HWEmotionKeyboard的initWithFrame:方法中创建上述两个自定义控件(设置背景色),在layoutSubviews中布局
3>先写外层,在表情键盘切换的响应方法里,使用HWEmotionKeyboard,设置给textView的inputView即可,设置键盘的宽高即可,x、y由系统决定(系统会弹出来)


注1:只要self.textView.inputView = nil;系统就默认弹出系统自带键盘

注2:在切换键盘时,需要先退出键盘,再弹出键盘,否则不能马上显示,也可以在键盘退出、弹出添加一个动画

注3:由于退出、弹出键盘添加了动画,又之前的键盘工具条会随着键盘的frame改变而改变位置,要保证在键盘切换的时候,工具条不懂,可以增加一个BOOL属性表示键盘是否在切换


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_02



注4:上述做法还有两个问题:

1. 键盘工具条按钮图片需要切换

2. 每次切换键盘的时候都是重新创建键盘,实际只需要创建一次即可


1.3 切换键盘工具条按钮图片



方法一:在HWComposeToolbar中添加键盘切换按钮属性,开放给外面使用,在监听到点击切换键盘按钮时,在外面给按钮设置图片


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情_03



注:这种方法不建议做,既然是自定义控件,最好封装彻底,屏蔽内部细节,不要让外面来直接改变控件内部的内容,改变控件内容应该是自定义控件内部来实现

方法二:将emotionButon私有化,同时提供一个BOOL属性表示是否需要显示表情键盘,重写setter方法,在里面修改按钮图片


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_键盘_04


1.4 表情键盘重复创建



懒加载

注意:这里一定要使用强指针,否则textView的inputView切换为nil的时候就会销毁,并初始化宽高!!!

2、工具条HWEmotionTabBar



注1:选项卡特点,按下去就切换,不用等到抬起来,而且选中一个后,直接切换,不需要高亮,再次点击也不会再显示高亮,因此需要自定义按钮,再重写setHighlighted:方法

注2:对按钮图片设置水平拉伸,且工具条高度是37

注3:记录点击按钮

注4:监听按钮点击,需要切换键盘,按钮点击在工具条中,切换键盘应该交由父控件键盘整体来做,使用代理

注5:使用枚举来表示哪个按钮点击

注6:按钮点击后,应该让那个按钮的点击事件取消,不要设置seleced状态,应设置disable状态


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_05



1>HWEmotionTabBar


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_控件_06


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_控件_07


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情_08


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_09



2>HWEmotionKeyboard


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_控件_10


3、加载表情数据



注1:emoji严格来讲不是图片,而是一个表情文字

注2:微博中掺杂图片,不是将图片发给新浪,而是发送图片对应的文字,只不过这个文字到时候显示在手机上需要解析成相应的图片

注3:assets只能放图片,不能放plist,将所有表情文件夹放到supportFiles,注意勾选下面一个,才能按文件夹分类


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_键盘_11


4、切换表情控件

4.1 表情数据模型

将上一节plist加载进来的数据传递给表情键盘控件HWEmotionListView,先将表情数据字典转模型,同时在控件中添加
/** 表情(里面存放的HWEmotion模型) */
@property(nonatomic, strong) NSArray *emotions;


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_控件_12

iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_13

问题:上述做法,每次点击都会重新加载文件,IO操作比较频繁,应该保证数据加载一份

方法一:对上面的数组分别进行懒加载,保证只加载一次,在切换的时候给listView设置不同的数组,但是这么做有个缺点,每次切换时需要先把以前的表情干掉,再设置新的表情数据,操作比较麻烦

方法二:弄四个listView控件,每个控件对应一组表情,方便管理,切换不同表情的时候即切换对应的控件即可,与tabBarController很类似,但是要注意每一个listView需要用强指针,否则切换的时候会销毁,而且不用一口气创建四个控件,需要用的时候创建即可


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_14

4.2 添加每组表情控件

iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_15

问题:设置四个表情控件的尺寸,之前是在layoutSubviews中设置,但是由于现在显示哪个控件是未知的,因此不太好在layoutSubviews中设置表情键盘尺寸

解决办法:添加一个属性,来容纳表情内容的控件

@property(nonatomic, weak) UIView *contentView;

将表情键盘放到contentView中,并且填充contentView,设置contentView的尺寸即可


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_16

iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_17

问题:当点击表情按钮显示表情键盘的时候,默认虽然选中了下面工具栏的默认按钮,但是由于是先创建tableBar,在init方法中选中了按钮,此时调用代理时代理还为空,创建完后再设置代理,因此,第一次不会调用代理方法,直到用户手动切换了不同表情组

HWEmotionTabBar *tabBar = [[HWEmotionTabBar alloc] init];
tabBar.delegate = self;


解决办法:重写代理的setter方法


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_18



框架以及搭建完成,接下来只需要根据listView中的表情模型数组,给listView添加表情图片即可!

5、表情分页

补充:上一节添加contentView的目的是为了更好的计算表情键盘的尺寸以及在键盘切换的时候移除原先的键盘,实际上没有contentView也是可以的,添加一个属性,表示当前显示的表情listView,并作相应修改即可

/** 保存正在显示listView*/
@property(nonatomic, weak) HWEmotionListView *showingListView;



iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_19


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_控件_20



接下来需要实现每个listView内部细节

1>里面分为两块,一块是scrollView显示表情页,一块是pageControl

2>重写listView中emotions的setter方法

3>使用KVC给pageControl设置图片

4>每一页的表情放在一个UIView容器中


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情_21


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_iOS开发_22


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_键盘_23


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情_24


6、显示表情



1>自定义HWEmotionPageView,继承自UIView,用来表示每一页的表情,并添加数组表示当前页的所有表情


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_表情_25



2>HWEmotionListView使用如下:


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_26



3>HWEmotionPageView中实现


iOS UITextView改变键盘按钮样式 ios切换键盘按钮_微博_27



注:emoji是字符串,将十六进制转为相应字符串即可