随着ios系統版本的更新,對原生emoji表情的支援也越來越豐富。emoji表情是unicode碼中為表情符号設計的一組編碼,當然,還有獨立于unicode的另一套編碼sbunicode,在os系統中,這兩種編碼都有很好的支援。ui系統會自動幫我們将編碼轉義成表情符号,例如用sbunicode如下代碼:
<a href="http://my.oschina.net/u/2340880/blog/529078#">?</a>
1
2
3
4
<code> </code><code>uilabel * label = [[uilabel alloc]initwithframe:cgrectmake(100, 100, 100, 100)];</code>
<code> </code><code>label.font = [uifont systemfontofsize:25];</code>
<code> </code><code>label.text = @</code><code>"\ue056"</code><code>;</code>
<code> </code><code>[self.view addsubview:label];</code>
就會在螢幕上出現一個笑臉:
首先為了實作跨平台,無論ios端,andorid端還是web端,都要有一個相同的标準,這個标準就可以是國際unicode編碼,我們的思路是将表情文字進行unicode編碼後再進行傳輸,是以,有兩中方式,一種是通過自定義一套表情切圖,将其與unicode碼一一對應,在轉碼的時候,我們一一周遊,轉換成unicode後進行傳輸,這樣的好處是我們可以保證所有平台所能使用的表情統一。在ios端,可以有另一種方式,通過上面我們知道,通過sbunicode碼我們可以在用戶端顯示表情符号,并且這個碼的排列是十分有規律的,通過這個特點,我們可以通過周遊sbunicode碼的範圍進行表情的建立,省去的圖檔素材的麻煩。
ios中可用的表情unicode範圍是:0xe001~0xe05a,0xe101~0xe15a,
0xe201~0xe253,0xe401~0xe44c,0xe501~0xe537。
我們可以通過周遊的方法,将其都加入資料源數組中:
5
6
7
8
9
10
11
<code>int</code> <code>emojirangearray[10] = {0xe001,0xe05a,0xe101,0xe15a,0xe201,0xe253,0xe401,0xe44c,0xe501,0xe537};</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>j = 0 ; j<10 ; j+=2 ) {</code>
<code> </code>
<code> </code><code>int</code> <code>startindex = emojirangearray[j];</code>
<code> </code><code>int</code> <code>endindex = emojirangearray[j+1];</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = startindex ; i<= endindex ; i++ ) {</code>
<code> </code><code>//添加到資料源數組</code>
<code> </code><code>[dataarray addobject:[nsstring stringwithformat:@</code><code>"%c"</code><code>, (unichar)i]];</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
鍵盤的擺放,可以通過collectionview來做,十分友善:
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<code> </code><code>//為了擺放分頁控制器,建立一個背景view</code>
<code> </code><code>bgview = [[uiview alloc]initwithframe:cgrectmake(0, 0, [uiscreen mainscreen].bounds.size.width, 200)];</code>
<code> </code><code>//分頁控制器</code>
<code> </code><code>pagecontrolbottom = [[uipagecontrol alloc]initwithframe:cgrectmake(0, 170, [uiscreen mainscreen].bounds.size.width, 20)];</code>
<code> </code><code>[bgview addsubview:pagecontrolbottom];</code>
<code> </code><code>//collectionview布局</code>
<code> </code><code>uicollectionviewflowlayout * layout = [[uicollectionviewflowlayout alloc]init];</code>
<code> </code><code>//水準布局</code>
<code> </code><code>layout.scrolldirection=uicollectionviewscrolldirectionhorizontal;</code>
<code> </code><code>//設定每個表情按鈕的大小為30*30</code>
<code> </code><code>layout.itemsize=cgsizemake(30, 30);</code>
<code> </code><code>//計算每個分區的左右邊距</code>
<code> </code><code>float</code> <code>xoffset = (kscreenwidth-7*30-10*6)/2;</code>
<code> </code><code>//設定分區的内容偏移</code>
<code> </code><code>layout.sectioninset=uiedgeinsetsmake(10, xoffset, 10, xoffset);</code>
<code> </code><code>scrollview = [[uicollectionview alloc]initwithframe:cgrectmake(0, 0, [uiscreen mainscreen].bounds.size.width, 160) collectionviewlayout:layout];</code>
<code> </code><code>//打開分頁效果</code>
<code> </code><code>scrollview.pagingenabled = yes;</code>
<code> </code><code>//設定行列間距</code>
<code> </code><code>layout.minimumlinespacing=10;</code>
<code> </code><code>layout.minimuminteritemspacing=5;</code>
<code> </code>
<code> </code><code>scrollview.delegate=self;</code>
<code> </code><code>scrollview.datasource=self;</code>
<code> </code><code>scrollview.backgroundcolor = bgview.backgroundcolor;</code>
<code> </code><code>[bgview addsubview:scrollview];</code>
在collectionview的回調方法中,處理如下:
27
28
29
30
31
32
33
34
35
36
37
38
<code>//每頁28個表情</code>
<code>-(nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section{</code>
<code> </code><code>if</code> <code>(((dataarray.count/28)+(dataarray.count%28==0?0:1))!=section+1) {</code>
<code> </code><code>return</code> <code>28;</code>
<code> </code><code>}</code><code>else</code><code>{</code>
<code> </code><code>return</code> <code>dataarray.count-28*((dataarray.count/28)+(dataarray.count%28==0?0:1)-1);</code>
<code> </code>
<code>}</code>
<code>//傳回頁數</code>
<code>-(nsinteger)numberofsectionsincollectionview:(uicollectionview *)collectionview{</code>
<code> </code><code>return</code> <code>(dataarray.count/28)+(dataarray.count%28==0?0:1);</code>
<code>-(uicollectionviewcell *)collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath{</code>
<code> </code><code>uicollectionviewcell * cell = [collectionview dequeuereusablecellwithreuseidentifier:@</code><code>"biaoqing"</code> <code>forindexpath:indexpath];</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i=cell.contentview.subviews.count; i>0; i--) {</code>
<code> </code><code>[cell.contentview.subviews[i-1] removefromsuperview];</code>
<code> </code><code>uilabel * label = [[uilabel alloc]initwithframe:cgrectmake(0, 0, 30, 30)];</code>
<code> </code><code>label.text =dataarray[indexpath.row+indexpath.section*28] ;</code>
<code> </code><code>[cell.contentview addsubview:label];</code>
<code> </code><code>return</code> <code>cell;</code>
<code>-(</code><code>void</code><code>)collectionview:(uicollectionview *)collectionview didselectitematindexpath:(nsindexpath *)indexpath{</code>
<code> </code><code>nsstring * str = dataarray[indexpath.section*28+indexpath.row];</code>
<code> </code><code>//這裡手動将表情符号添加到textfield上</code>
<code>//翻頁後對分頁控制器進行更新</code>
<code>-(</code><code>void</code><code>)scrollviewdidscroll:(uiscrollview *)scrollview{</code>
<code> </code><code>cgfloat contenoffset = scrollview.contentoffset.x;</code>
<code> </code><code>int</code> <code>page = contenoffset/scrollview.frame.size.width+((</code><code>int</code><code>)contenoffset%(</code><code>int</code><code>)scrollview.frame.size.width==0?0:1);</code>
<code> </code><code>pagecontrolbottom.currentpage = page;</code>
uitextfield和uitextview都會有下面這個屬性和方法:
<code>@property (nullable, readwrite, strong) uiview *inputview; </code>
<code>- (</code><code>void</code><code>)reloadinputviews;</code>
inputview我們可以設定textview和textfield成為第一響應時的彈出附件,如果我們不設定或者設定為nil,則會彈出系統鍵盤,reloadinputview方法可以使我們重新整理這個附件視圖,通過這兩個,我們可以非常輕松的實作鍵盤的切換,比如我們在一個出發方法中如下處理:
<code>-(</code><code>void</code><code>)imageviewtap{</code>
<code> </code><code>if</code> <code>(![_publishcontent isfirstresponder]) {</code>
<code> </code><code>return</code><code>;</code>
<code> </code><code>if</code> <code>(isemoji==no) {</code>
<code> </code><code>isemoji=yes;</code>
<code> </code><code>//呼出表情</code>
<code> </code><code>_textview.inputview=bgview;</code>
<code> </code><code>[_textview reloadinputviews];</code>
<code> </code><code>isemoji=no;</code>
<code> </code><code>_textview.inputview=nil;</code>
效果如下:
追注:測試上面的sbunicode碼在模拟器上可以正常顯示,真機并不能識别,可以通過将表情符全部添加到一個plist檔案中,通過檔案讀取來建立鍵盤的方式進行真機上的開發。plist檔案位址如下:
<a href="http://pan.baidu.com/s/1o6adkbw" target="_blank">http://pan.baidu.com/s/1o6adkbw</a>