自定義表情鍵盤
表情包含:默認谓娃、Emoji和浪小花
提供方式:bundle文件
框架結(jié)構(gòu):
自定義表情鍵盤.png
分析:
目前有一維數(shù)組:
- 默認表情 一共108個
- emoji表情 一共80個
- 浪小花 一共40個
把以上的一維數(shù)組轉(zhuǎn)成二維數(shù)組
表情分類: 每一個一維數(shù)組中包含元素個數(shù): 索引:
默認表情 [20 20 20 20 20 8] 0 - 19 , 20 - 39 ..... ,100- 107
emoji表情 [20 20 20 20 ] 0 - 19 , 20 - 39 , 40 -59
浪小花 [20 20] 0 - 19 , 20 - 39
代碼實現(xiàn):
① 因為表情信息會多次使用,所以提供一個全局訪問點,便于使用
//全局訪問點(單例)
static let sharedTool: JSEmoticonTool = JSEmoticonTool()
② 獲取表情包bundle路徑
// 懶加載獲取Bundle
lazy var emoticonBundle: NSBundle = {
// 獲取bundle路徑
let path = NSBundle.mainBundle().pathForResource("Emoticons.bundle", ofType: nil)!
// 獲取bundle
let bundle = NSBundle(path: path)!
// 返回bundle
return bundle
}()
③ 提供一個公共方法,從bundle中的plist文件提取出一維數(shù)組
// MARK: - 讀取plist文件中的數(shù)組,轉(zhuǎn)成模型一維數(shù)組
private func getEmoticons(fileName: String) -> [JSEmoticonModel] {
///...Classes/Compose/View/Emoticon/Emoticons.bundle/Contents/Resources/emoji/info.plist
// 讀取plist文件中的數(shù)組轉(zhuǎn)成模型一維數(shù)組
// 文件路徑
let file = emoticonBundle.pathForResource("\(fileName)/info.plist", ofType: nil)!
// plist文件轉(zhuǎn)數(shù)組
let array = NSArray(contentsOfFile: file)!
// 創(chuàng)建可變臨時數(shù)組
var tmpArr: [JSEmoticonModel] = [JSEmoticonModel]()
// 遍歷Array
for dict in array {
// KVC 字典轉(zhuǎn)模型
let element = JSEmoticonModel(dict: dict as! [String: AnyObject])
// 保存模型
tmpArr.append(element)
}
// 返回存放模型的一維數(shù)組
return tmpArr
}
補充
- pathForResource獲取到的路徑并不完整,只能獲取到bundle的Resources文件夾,所以進行了拼接,得到完整的路徑
bundle_path.png
- 并且bundle中存放的圖片無法直接通過轉(zhuǎn)模型后的圖片名直接使用,需要根據(jù)導入的bundle文件拼接完整路徑才可以
// 圖片表情
// 從模型中獲取補充的路徑名
let path = emoticonModel.path ?? ""
// 從模型中獲取圖片的名稱
let png = emoticonModel.png ?? ""
// 拼接圖片的全路徑
let name = path + png
let image = UIImage(named: name, inBundle: JSEmoticonTool.sharedTool.emoticonBundle, compatibleWithTraitCollection: nil)
button.setImage(image, forState: UIControlState.Normal)
④ 根據(jù)公共方法懶加載表情數(shù)據(jù),得到的是一維數(shù)組
// default 表情 : 一維數(shù)組
lazy var defaultEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("default/")
}()
// emoji 表情 : 一維數(shù)組
lazy var emojiEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("emoji/")
}()
// 浪小花 表情 : 一維數(shù)組
lazy var lxhEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("lxh/")
}()
⑤ 根據(jù)表情鍵盤布局規(guī)則,將一維數(shù)組轉(zhuǎn)二維數(shù)組
// 顯示列數(shù)
let EmoticonMaxCol = 7
// 顯示行數(shù)
let EmoticonMaxRow = 3
// 每頁顯示的個數(shù)
let EmoticonMaxCount = EmoticonMaxCol * EmoticonMaxRow - 1
每一頁顯示固定的表情個數(shù),所以需要將一維數(shù)組重新按照每頁顯示表情個數(shù)重新分組
遍歷每一個一維數(shù)組,將一維數(shù)組轉(zhuǎn)成二維數(shù)組
// MARK: - 一維數(shù)組轉(zhuǎn)二維數(shù)組
func getEmoticonsGroup(emoticons: [JSEmoticonModel]) -> [[JSEmoticonModel]] {
// 計算頁數(shù)
let pageCount = (emoticons.count + EmoticonMaxCount - 1) / EmoticonMaxCount
// 創(chuàng)建一個臨時的可變的二維數(shù)組
var tempArray:[[JSEmoticonModel]] = [[JSEmoticonModel]]()
// 遍歷一維數(shù)組(正序) 截取一維數(shù)組
for i in 0..<pageCount {
// 位置和長度
let loc = EmoticonMaxCount * i
var len = EmoticonMaxCount
// 避免數(shù)組越界
if loc + len > emoticons.count {
len = emoticons.count - loc
}
// 截取范圍
let range = NSMakeRange(loc, len)
// 數(shù)組的截取
let arr = (emoticons as NSArray).subarrayWithRange(range) as! [JSEmoticonModel]
// 保存一維數(shù)組
tempArray.append(arr)
}
// 返回二維數(shù)組
return tempArray
}
⑥ 最后將得到的二維數(shù)組合成為三維數(shù)組
// 表情 : 三維數(shù)組
lazy var allEmoticons: [[[JSEmoticonModel]]] = {
return [
self.getEmoticonsGroup(self.defaultEmoticons),
self.getEmoticonsGroup(self.emojiEmoticons),
self.getEmoticonsGroup(self.lxhEmoticons)
]
}()
這樣,再通過CollectionView分配數(shù)據(jù)時:
三維數(shù)組的長度 --> CollectionView --> NumberOfSection
二維數(shù)組的長度 --> CollectionView --> NumberOfItemInSection
一維數(shù)組的元素 --> CollectionView --> Cell所需數(shù)據(jù)
// 數(shù)據(jù)源方法
extension JSEmojiconPageView: UICollectionViewDataSource {
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return JSEmoticonTool.sharedTool.allEmoticons.count
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return JSEmoticonTool.sharedTool.allEmoticons[section].count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewCellId, forIndexPath: indexPath) as! JSEmojiconPageViewCell
cell.indexpath = indexPath
cell.emoticons = JSEmoticonTool.sharedTool.allEmoticons[indexPath.section][indexPath.item]
return cell
}
}