天天看點

iOS自定義的emoji表情鍵盤

        随着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自定義的emoji表情鍵盤

        首先為了實作跨平台,無論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&lt;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&lt;= 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&gt;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>

效果如下:

iOS自定義的emoji表情鍵盤

追注:測試上面的sbunicode碼在模拟器上可以正常顯示,真機并不能識别,可以通過将表情符全部添加到一個plist檔案中,通過檔案讀取來建立鍵盤的方式進行真機上的開發。plist檔案位址如下:

<a href="http://pan.baidu.com/s/1o6adkbw" target="_blank">http://pan.baidu.com/s/1o6adkbw</a>

繼續閱讀