當下髮狀態和發評論已經漸漸成為不少軟體的必備功能,這兩者功能基本類似。但是有普通編輯和高階編輯之分,普通的評論只能發文字,一旦可以傳送表情(非emoji表情)就需要用到圖文混排。並且系統只能提供emoji表情,要用到其他自定義表情需要自行新增表情鍵盤。
因為表情鍵盤和圖文混排寫在一起太長了分為兩期。本期以新浪微博的發微博頁面為例,整理新增表情鍵盤的步驟,下期會總結自己在編寫圖文混排中遇到的種種問題和解決方案。基本的頁面類似於這樣,有部分細節沒做不過也無關大雅了。編寫的語言用的是swift
如果你不是在董鉑然部落格園看到本文,請點選檢視原文。
我表情鍵盤的做法是,在釋出微博控制器頁面底部新增一個toolbar 然後底部的約束拖一根線到控制器裡,可以根據監聽鍵盤的彈出動態修改。
下面的表情鍵盤是新建一個xib或者storyboard 建一個普通控制器,上面放collectionView,下面放一個view或者toolbar顯示錶情的種類。
collectionViewCell內部放一個imageView 和 一個Label。因為emoji表情是需要用label顯示的。
下圖是兩個設計介面
左邊的撰寫微博控制器和上面的效果截圖有些不同。因為設定了導航欄的顏色主題是黃色。裡面灰色的placeholder請釋出微博是用程式碼新增的設定為textView的子控制元件。上面的設定可以自行腦補在此不作過多贅述了,本文主要是總結表情鍵盤和圖文混排
右邊的表情鍵盤控制器也是可以清楚地看到cell裡有imgView和label
這裡記得要在撰寫微博控制器裡設定,點選小圓臉就設定第一響應者,並且把彈出鍵盤的inputView設定成我們自定義的這個表情鍵盤控制器。
然後就是裡面cell的流水佈局,把控制器裡的佈局拖到控制器中修改
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupLayout()
}
func setupLayout(){
let row:CGFloat = 3
let col:CGFloat = 7
let m:CGFloat = 10
let screenSize = self.collectionView.bounds.size
let w = (screenSize.width - (col + 1) * m) / col
layout.itemSize = CGSizeMake(w, w)
layout.minimumInteritemSpacing = m
layout.minimumLineSpacing = m
/// 每一組之間的邊距
layout.sectionInset = UIEdgeInsetsMake(m, m, m, m)
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
collectionView.pagingEnabled = true
}
之所以寫在ViewDidLayoutSubViews方法中,是為了等前面的佈局完全載入好。
佈局完畢後應該就是可以看到此效果。
然後就是載入表情圖片,把表情圖片依次填到這些方框中
表情圖片的載入方法:
1.下載個新浪微博的ipa解壓,在裡面能夠找到所有的表情包都是裝在一個emticons資料夾裡
2.資料夾中有個emoticons.plist檔案,裡面是一個陣列,裡面包含四個字典分別是四種表情的各項引數。和四個資料夾裡裝著四種表情
3.每一種表情的資料夾裡還有一個info.plist檔案,這個檔案裡是個字典包含幾個自己表情引數和一個陣列,裡面裝的是本類別的所有表情
4.這裡面的引數目測應該就能看懂分別是幹什麼的 如圖
5.這裡載入表情圖片時要注意不能直接使用第三方框架字典轉模型,因為字典轉模型之後的模型陣列內值都是連續的,但是每頁的右下角還需要新增一個刪除按鈕,所以產生矛盾
6.所以載入表情圖片的基本思路是,手寫方法一層一層載入,先把emoticons.plist轉模型,再通過裡面的path可以取到每一個info.plist再轉模型。
7.然後info.plist中有一個陣列裡裝著所有的表情,每一個表情又是一個字典再給他轉模型。並設定個模型陣列
8.前面設定collectionView的佈局是3*7,這裡就設定collectionView的Section每組21個,除去一個刪除按鈕正好是每頁20個表情。
9.把模型和模型陣列整理好,該addObject的就addObject。
最後在資料來源方法中載入:
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
/// 返回有幾種表情
return emoticonSection?.count ?? 0
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
/// 返回每個種類中的表情數量
return emoticonSection![section].emoticons.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("EmoticonsCell", forIndexPath: indexPath) as! EmoticonCell
/// 屬性賦值
cell.emoticon = emoticonSection![indexPath.section].emoticons[indexPath.item]
return cell
}
至於cellForItem裡的屬性賦值,是在自定義的EmoticonCell裡設定didSet判斷模型的種類(是否是emoji表情)再完成資料分發
/// 自定義表情cell
class EmoticonCell: UICollectionViewCell {
@IBOutlet weak var iconView: UIImageView!
@IBOutlet weak var emojiLabel: UILabel!
var emoticon: Emoticon? {
/// 賦值完成後呼叫
didSet {
if let path = emoticon?.imagePath {
iconView.image = UIImage(contentsOfFile: path)
} else {
iconView.image = nil
}
emojiLabel.text = emoticon?.emoji
// 是否是刪除按鈕
if emoticon!.isDeleteButton {
iconView.image = UIImage(named: "compose_emotion_delete_highlighted")
}
}
}
}
之後表情鍵盤就可以如圖的顯示了。
然後就是監聽每個按鈕表情的點選事件。這裡需要用到代理。
定義一個協議協議裡有個方法點選時把自己(表情控制器)和點中的表情模型傳過去
再在collectioView的代理方法中設定didSelected觸發
協議:
protocol EmoticonsViewControllerDelegate: NSObjectProtocol {
/// 選中了某一個表情
func emoticonsViewControllerDidSelectEmoticon(vc:SXEmoticonsViewController, emoticon: Emoticon)
}
代理方法:
/// 根據 indexPath 返回表情資料
func emoticon(indexPath: NSIndexPath) -> Emoticon {
return emoticonSection![indexPath.section].emoticons[indexPath.item]
}
/// cell 被選中
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// 使用 ? 不需要判斷代理是否實現方法
delegate?.emoticonsViewControllerDidSelectEmoticon(self, emoticon: emoticon(indexPath))
}
在撰寫微博控制器裡,接收到資料模型後能列印出來就證明前面的表情鍵盤都做好了。
如果你不是在董鉑然部落格園看到本文,請點選檢視原文。
正在整理圖文混排,有興趣的可以關注