自定義表情鍵盤
表情包含:默認、Emoji和浪小花
提供方式:bundle文件
框架結構:
自定義表情鍵盤.png
分析:
目前有一維數組:
- 默認表情 一共108個
- emoji表情 一共80個
- 浪小花 一共40個
把以上的一維數組轉成二維數組
表情分類: 每一個一維數組中包含元素個數: 索引:
默認表情 [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
代碼實現:
① 因為表情信息會多次使用,所以提供一個全局訪問點,便于使用
//全局訪問點(單例)
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文件提取出一維數組
// MARK: - 讀取plist文件中的數組,轉成模型一維數組
private func getEmoticons(fileName: String) -> [JSEmoticonModel] {
///...Classes/Compose/View/Emoticon/Emoticons.bundle/Contents/Resources/emoji/info.plist
// 讀取plist文件中的數組轉成模型一維數組
// 文件路徑
let file = emoticonBundle.pathForResource("\(fileName)/info.plist", ofType: nil)!
// plist文件轉數組
let array = NSArray(contentsOfFile: file)!
// 創建可變臨時數組
var tmpArr: [JSEmoticonModel] = [JSEmoticonModel]()
// 遍歷Array
for dict in array {
// KVC 字典轉模型
let element = JSEmoticonModel(dict: dict as! [String: AnyObject])
// 保存模型
tmpArr.append(element)
}
// 返回存放模型的一維數組
return tmpArr
}
補充
- pathForResource獲取到的路徑并不完整,只能獲取到bundle的Resources文件夾,所以進行了拼接,得到完整的路徑
bundle_path.png
- 并且bundle中存放的圖片無法直接通過轉模型后的圖片名直接使用,需要根據導入的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)
④ 根據公共方法懶加載表情數據,得到的是一維數組
// default 表情 : 一維數組
lazy var defaultEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("default/")
}()
// emoji 表情 : 一維數組
lazy var emojiEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("emoji/")
}()
// 浪小花 表情 : 一維數組
lazy var lxhEmoticons: [JSEmoticonModel] = {
return self.getEmoticons("lxh/")
}()
⑤ 根據表情鍵盤布局規則,將一維數組轉二維數組
// 顯示列數
let EmoticonMaxCol = 7
// 顯示行數
let EmoticonMaxRow = 3
// 每頁顯示的個數
let EmoticonMaxCount = EmoticonMaxCol * EmoticonMaxRow - 1
每一頁顯示固定的表情個數,所以需要將一維數組重新按照每頁顯示表情個數重新分組
遍歷每一個一維數組,將一維數組轉成二維數組
// MARK: - 一維數組轉二維數組
func getEmoticonsGroup(emoticons: [JSEmoticonModel]) -> [[JSEmoticonModel]] {
// 計算頁數
let pageCount = (emoticons.count + EmoticonMaxCount - 1) / EmoticonMaxCount
// 創建一個臨時的可變的二維數組
var tempArray:[[JSEmoticonModel]] = [[JSEmoticonModel]]()
// 遍歷一維數組(正序) 截取一維數組
for i in 0..<pageCount {
// 位置和長度
let loc = EmoticonMaxCount * i
var len = EmoticonMaxCount
// 避免數組越界
if loc + len > emoticons.count {
len = emoticons.count - loc
}
// 截取范圍
let range = NSMakeRange(loc, len)
// 數組的截取
let arr = (emoticons as NSArray).subarrayWithRange(range) as! [JSEmoticonModel]
// 保存一維數組
tempArray.append(arr)
}
// 返回二維數組
return tempArray
}
⑥ 最后將得到的二維數組合成為三維數組
// 表情 : 三維數組
lazy var allEmoticons: [[[JSEmoticonModel]]] = {
return [
self.getEmoticonsGroup(self.defaultEmoticons),
self.getEmoticonsGroup(self.emojiEmoticons),
self.getEmoticonsGroup(self.lxhEmoticons)
]
}()
這樣,再通過CollectionView分配數據時:
三維數組的長度 --> CollectionView --> NumberOfSection
二維數組的長度 --> CollectionView --> NumberOfItemInSection
一維數組的元素 --> CollectionView --> Cell所需數據
// 數據源方法
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
}
}